Problem:
You have the following URLs for your website:
www.example.com/about-us.html
www.example.com/services.html
www.example.com/contact-us.html
However, you would like to hide file extensions from the end users, and allow them to access to the files using the following URLs:
www.example.com/about-us
www.example.com/services
www.example.com/contact-us
Solution:
The solution can be achieved by using Apache's mod_rewrite. Create an .htaccess file in your website root directory with the following content.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}!-d
RewriteCond %{REQUEST_FILENAME}!-f
RewriteRule ^([^.]+)\.html$ $1 [L]
# Replace html with your file extension, eg: php, htm, asp
Correction
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.*)$ $1.html # Replace html with your file extension, eg: php, htm, asp
Many thanks to Binh Nguyen (Commenter #1) for the correction
To add a trailing slash at the end of the URL
(for example: http://www.example.com/about-us/ to go to http://www.example.com/about-us.html)
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^([^/]+)/$ $1.html # Forces a trailing slash to be added RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$ RewriteRule (.*)$ /$1/ [R=301,L]
Benefits:
- Search engine friendly
- Easier to read and remember
- Extension/environment independent; when you change the technology used for your website (for eg: from using asp to php), you can be assured that all the links and bookmarks will still work.
ERRRH!!! Your code doesn’t work.
I got this error message:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, support@bonaway.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
The real working code should be like this:
For PHP
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Binh Nguyen is correct, the code in this article will cause an internal error. However, his code is great! Worked a charm!
The article’s code gives me an internal error but I’m getting page not found with Nguyen’s code
Oops wrong page. It actually works. Now I just have to remove all the extensions from my links.
Do I have to get rid of the .php in my files, can’t it do it automatically?
@kevin
yes, this is what the rewrite code is all about. the php files remain, but the browser gets a cleaner url. just make sure you update your links by dropping the extension, and you’ll be all set.
it works fine but how to prevent users from using .php extention if they type it manualy instead it shows error page?
Thanks….let me try!
Is it possible to add an ending “/” to the URL so that it looks like a directory?
i.e., http://www.example.com/services/
The current code generates an error done like this.
Hello! I would also like to know how to make it with a “/” on the end.
I am changing a wordpress blog to a static site, so this would be really helpful!
To add / at the end
Replace the last line of code:
RewriteRule ^(.*)$ $1.html
With these lines:
RewriteRule ^([^/]+)/$ $1.html
# Forces a trailing slash to be added
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
I used this code
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
# Forces a trailing slash to be added
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
and it would not work and if i remove html at end it will show me a page but it would not load CSS Help please?????
Hi Paul, can you give me the URL of the page so that I can have a look for you? You should be able to fix the css issue by using an absolute path, rather than a relative one.
hey, good thread & got the right answers. thanks everybody!
one question, how to deal with situation where two files have the same name but different extensions?
e.g., in the same directory:
foo.html
foo.php
the links would both be href=”foo” with this method, how does one deal with this? (assuming the file names must not change)
Hello!
Thanks for the tips! I am also having the same problem as Paul described. The css file is not loading and the images also not! Any more tips?
I tried doing it with the absolute path and it works. The images don’t work though!
Can this be done without changing the filepath of the css and the images?
The problem is that it gives an error when I put in the url with the / at the end. Can it redirect to the version without the slash?
Great Article really needed this
If you make all of your links absolute it works ( absolute url to your css files, image files etc )
Hi
I have both .html and .php pages and would like to hide both extensions on the same site using one .htaccess file – is this a possibility, if so, it would be appreciated if you could make an update to this post.
Thanks
Hello Eisabai,
I digged a lot of sources looking for a good reference of this issues and I’m so glad to find your website.
Your article is the best. Thank you and thanks to all people who commented above and contributed to correcting and improving this code.
BTW, I had the same problem that some people mentioned before – with CSS and images. I solved it with ../ in my relative path.
Hi…
trailing slash function working but dnt show
images & css :(
plz mail me the correct …
Will this code work for .shtml extension?
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.shtml -f
RewriteRule ^(.*)$ $1.shtml
Hi miva,
Yes, I believe so.
Would this work for php,html,css,jpg,gif,png?
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.(php|html|css|jpg|gif|png) -f
RewriteRule ^([^/]+)/$ $1.html
I have tried all of the above, it shows the 403 error(((
Forbidden
You don’t have permission to access /accessories/ on this server.
Code works a dream. Now I have /something and no longer /something.html
Next issue though ….. I do not want to set up 301 redirects for every single page, from the /something.html version to /something
Is there a single piece of code I can insert into the .htaccess file to solve this or am I facing having to set up 40+ 301 redirects?
Hope somone can advise,
jen
DUDE! I searched high and low for something like this and after a day of searching and trying to tweak it myself, I found this page.
You are a lifesaver.
THANK YOU!
Hey this is kewl and I can get it to work for files in the root dir but how can I get it to work for subdirectories?
I’ ve got the same question as Peter, How do you make this work for sub domains, if you have http://www.dev.mysite.com/test.html –> http://www.dev.mysite.com/test/
My husband and I just started our small website hosting business we just acquired our first 3 domains and we are looking towards growing it. I’m searching the internet for techniques and most up-to-date trends to advertise our domains and maybe do some search engine marketing on it. Recognize the value of the time you put in to share this with us.
Thanks very much! A small but very useful code snippet. Use if the htaccess file and its powerfulness is often overlooked.
Hi,
Thank you for your Tips..
But i want to know that this code will work as a 301 redirect?
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Let me know?
Thanks
Raj
Awesome! Thank you for a great tutorial – I had a few issues but the comments helped me out!
Thanks…. For the code….
Little bit complex… But Okay, Will try to crack it.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
This code is not working, what might be the reason?
can anyone help me. M just trying to remove the extension .php. But its showing page not found…. Pl Pl Pl Help……..
Great tip, I am trying to get it to work. So if I understand this correctly, we have to delete the extensions from the webpages for this to work?
I tried the following code:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
And it makes so http://website.com/folder/file.html works, http://website.com/folder/file/ works, but http://website.com/folder/file takes me to http://website.com/file/
I’d like it to work without the slash and extension too, how do I do this?
Hi I’ve been searching for hours and still can’t make it to work.. where would I create a htaccess file? the same directory as my pages? C:/wamp/www/folder/index.php
I get Internal Server Error. What should I do?
Hey Randy,
The .htaccess file needs to go in the same directory as the file. It will work from the top down. Meaning, if you have the .htaccess in a certain directory, it will affect any other sub files/folders within it.
i got below error
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, admin@localhost and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
made a file name “.htaccess”
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
and put in same folder but it show above error
what should i do?
Yo Man!
The code is not working for me. I still get 404. This is the line from Apache log:
127.0.0.1 – – [18/Mar/2011:02:42:45 +0530] “GET /t HTTP/1.1” 404 1161 “-” “Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.62 Version/11.01”
Somebody please help!
hi adway
this code worked for me:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_fileNAME} !-d
RewriteCond %{REQUEST_fileNAME} !-f
RewriteRule ^(([^/]+/)*[^./]+)$ /$1.html [L]
ah, and one other note: if you happen to have an edge case like this where the directory the file is in and the file name have the same name like e.g. so:
plugins\skills\skills.html
the engine gets confused. you need to rename skills.html to sth else like skills-temp.html and then need to add an exception to .htaccess like so:
RewriteEngine on
RewriteBase /
RewriteCond %{DOCUMENT_ROOT}/$1 !-f
RewriteCond %{DOCUMENT_ROOT}/$1/ !-d
#this is the exception
RewriteRule ^plugins/skills/$ /plugins/skills-temp.html [L]
RewriteRule ^(([^/]+/)*[^./]+)$ /$1.html [L]
there might be a more elegant solution to solve this edge case where you don’t need to define an exception in .htaccess but i have not found it yet and to be honest that whole rewrite rules thing hurts my brain ;-)
cheers
sissi
Thanks for the tips and codes to hide file extension. URLs look more SEO friendly hiding extensions. Nice blog.