Snippets, Tutorials

Removing file extension via .htaccess

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.

45 thoughts on “Removing file extension via .htaccess

  1. 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

  2. Binh Nguyen is correct, the code in this article will cause an internal error. However, his code is great! Worked a charm!

  3. The article’s code gives me an internal error but I’m getting page not found with Nguyen’s code

  4. Oops wrong page. It actually works. Now I just have to remove all the extensions from my links.

  5. Do I have to get rid of the .php in my files, can’t it do it automatically?

  6. @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.

  7. it works fine but how to prevent users from using .php extention if they type it manualy instead it shows error page?

  8. 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!

  9. 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]

  10. 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?????

  11. 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.

  12. 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)

  13. 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?

  14. 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?

  15. If you make all of your links absolute it works ( absolute url to your css files, image files etc )

  16. 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

  17. 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.

  18. Hi…

    trailing slash function working but dnt show
    images & css :(

    plz mail me the correct …

  19. Will this code work for .shtml extension?

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME}\.shtml -f
    RewriteRule ^(.*)$ $1.shtml

  20. Hi miva,

    Yes, I believe so.

  21. 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

  22. I have tried all of the above, it shows the 403 error(((

    Forbidden
    You don’t have permission to access /accessories/ on this server.

  23. 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

  24. 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!

  25. 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?

  26. 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.

  27. Thanks very much! A small but very useful code snippet. Use if the htaccess file and its powerfulness is often overlooked.

  28. 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

  29. Awesome! Thank you for a great tutorial – I had a few issues but the comments helped me out!

  30. RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME}\.php -f
    RewriteRule ^(.*)$ $1.php

  31. 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……..

  32. 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?

  33. 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?

  34. 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.

  35. 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?

  36. 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!

  37. hi adway

    this code worked for me:

    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_fileNAME} !-d
    RewriteCond %{REQUEST_fileNAME} !-f
    RewriteRule ^(([^/]+/)*[^./]+)$ /$1.html [L]

  38. 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

  39. Thanks for the tips and codes to hide file extension. URLs look more SEO friendly hiding extensions. Nice blog.

Comments are closed.

Twitter
LinkedIn
YouTube
Instagram