Remove File Extension from URLs

So you want Pretty URLs?

You have a site with index.php or index.html files and you want to create friendly URLs. A simple script I have been working on now for a few years this file is a .htaccess file and must live in the root of your domain so for example

Just as an FYI for anyone using or editing this, if you do not know what this is then check out more about friendly URLs and the concept of mod rewrite before adding this. If you experience and 500 errors or anything like that please remove the script.

The Code

AddType text/x-component .htc
RewriteEngine On
RewriteBase /
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]

What it Does?

This handy script will remove all .php extensions creating lovely SEO and human friendly URLs for your static site, it will also not mess up any exisiting folders that you have live on your domain.

Questions, comments or amends please let me know here.


  1. Maxim
    February 20, 2013 at 3:57 pm

    Frankly speaking, this is the only code that removes php extension on my website.
    Yes, it works on each page except index.php. As soon as I get to the home page, I get stuck. Every click to any link returns 404. Help?

  2. Niall Flynn
    February 20, 2013 at 4:07 pm

    Is this on working for me on FireFox, email me a link I will get it sorted for you in 30 secs :)

  3. Maxim
    February 20, 2013 at 4:30 pm

    Fixed! It was my fault. Thank you for your code.
    There just one problem that I don’t know how to resolve. On my left menu there are three first links that do not work if I change them this way:

    a href=”catalogue.php” —-> :-)
    a href=”” –> :-(

    The requested URL / was not found on this server.

  4. Niall Flynn
    February 20, 2013 at 4:32 pm

    Looks like bad links, make sure you are linking to the friendly ones now and check your references, use things like ./ and ./link rather than exact URLs

  5. Maxim
    February 20, 2013 at 7:13 pm

    Thank you Niall for your advise concerning website internal links. It works…

  6. Robert
    February 27, 2013 at 4:14 am

    Hi Niall,

    Your code has gotten me the furthest thus far however it is still not bringing up the linked pages.

    The error can be seen when any of the page links in the main nav are clicked.

    I can see the URL rewriting itself to exclude the .php but now I am receiving a “Not Found” error.

    Your assistance would be greatly appreciated!

    Thanks in advance.

    • Niall Flynn
      February 28, 2013 at 1:39 am

      Check the Link Setting within WordPress itself, you need to add the settings file and update the permalinks to the best of my knowledge.

  7. joeynobody
    March 6, 2013 at 7:02 pm

    Really appreciate a brother like you! I’m a novice at best and this code did the trick. You the man.

  8. moe
    March 9, 2013 at 7:05 pm

    Hi there, great post!

    Is there a way to add the / after the urls?

    for example, using that script, i get

    is there a way to make it


  9. Niall Flynn
    March 9, 2013 at 7:11 pm

    Try pulling out;
    # remove slash if not directory
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} /$
    RewriteRule (.*)/ $1 [R=301]

    I won’t get a chance to play around with this but if you figure it out please let me know.

  10. Esben Thomsen
    March 29, 2013 at 9:31 am

    You are a genius! I’ve tried many combinations, but this is just as smooth and perfect as it should be, thanks for sharing – you just saved me a lot of hair pulling

  11. Thomas
    April 1, 2013 at 5:27 pm

    Thanks for this – I’m also interested in adding a trailing slash to the URL – I have tried removing the section you suggested but it doesn’t seem to make any difference.

    Any ideas? Many thanks.

  12. David Joyce
    April 3, 2013 at 4:17 pm

    This works really well for me so far! However, is there a way to allow for the addition of variables within the URL segments separated by a slash?

    So for example, I have template.php, and I want my URL to be

    So template.php is loaded and the rest is ignored. Then in the template I can parse the URL for the values in each segment.

  13. David Joyce
    April 3, 2013 at 4:19 pm

    I imagine if this is possible though, the rule would have to be specific to template.php page so as not to interfere with directories.

  14. Niall Flynn
    April 7, 2013 at 12:04 pm

    Tricky, I guess yeah you would need some sort of rule, I want to keep this script as simple as possible so I might bow out of trying to implement that but if you get a fix drop it in here, if you feel like sharing.

  15. David
    April 9, 2013 at 7:31 pm

    Amazing, thank you! I’ve tried the solutions from 100 different sites, and this was the first one that worked. Much appreciated!

  16. Niall Flynn
    April 10, 2013 at 1:21 pm

    Tip of the hat in return. Yeah this script is great, just works.

    I know there are a few comments around ad-hoc/strange wants/needs but overall it fixes it all up and on most Apache configs just works as is.

  17. Clayton
    April 18, 2013 at 9:16 pm

    Added the code, worked like a charm, but keep getting 404 messages. Tried to change my links to remove the .php from them and just screwed everything up even more. Hosting with GoDaddy right now.

    Email would be best to contact for help.

    Thanks in advance!!

  18. Eric
    April 30, 2013 at 2:13 am

    Thanks for the code. I am adding it to a second site right now. Wondering if there are special considerations when combining that code with 301 redirects that are also in the htaccess file. Which should come first? Does your code need to be separated at all?

  19. Niall Flynn
    April 30, 2013 at 11:02 pm

    Redirects first I assume, not sure I would just try both, if it works, it works :)

    Test it in IE too bound to be the place it will show up if there is.

  20. Nathan Lyle
    May 13, 2013 at 7:04 am

    Have been beating my head against htaccess for a few hours tonight… had it to where the URLs were being rewritten fine in terms of how they looked, but if someone typed it by hand with a trailing slash it generated the 500 server error. (Guessing there was a loop problem.) In any case, your example worked around that perfectly. I was giving hope that I’d fix this without first having to become an htaccess expert… but now I can take a bit more of the relaxed approach to learning instead of panic to get my site working. lol
    Thanks for sharing!

  21. Niall Flynn
    May 13, 2013 at 11:52 am

    No problem love the space theme on your site I did the same for my WordPress SEO site.

  22. Brian
    May 24, 2013 at 4:21 am

    Hi Niall,

    Thanks for sharing the code.

    I’m building my site with .html files, and was wondering if the code is the same for removing the .html extension?
    Should I just replace every instance of “php” in the code with “html”?

  23. Brian
    May 24, 2013 at 5:20 am

    I changed the “php” to “html” and tried it.

    It works in IE and Firefox perfectly, but in Chrome, it only worked on three of the 5 pages…index.html and /Services.html still show the extensions.
    Any thoughts?


  24. Niall Flynn
    May 24, 2013 at 10:37 am

    Strange can you send me a link

  25. Sean
    June 3, 2013 at 1:26 am


    Well, after reading up for weeks on trimming the URLs using mod rewrite, THIS method works as soon as I placed it into .htaccess. Perfect so far with zero issues.

    Now, all I need find out is how to change this: to something like – tap-shoes is the category name.

    Any ideas?

  26. Bobby Patterson
    June 6, 2013 at 4:56 pm

    Is there a way to modify the script so it works in a testsite folder within the root folder? For example make it work like this

    It works wonderfully on the root level, but the site I have at root level doesn’t have any pages within directories so I can’t really test that there.

  27. Niall Flynn
    June 12, 2013 at 9:25 am

    @Sean doable, send me an email

    @Bobby Look up the comments I think someone else had this issue and solved it baseurl to the best of my knowledge. Either that or just setup as the test URL

  28. Jon
    July 4, 2013 at 12:57 pm

    Hey there,

    This is my first time dealing with this but I have read a great deal about this particular code. My question now is, which I am unable to find on the Internet, how do remove the file extension if my website has both .php and .html?

    My CMS requires .php while the rest of my webpages are in .html. So I have been pulling my hair to find the solution.

    Hope to see ye reply! Thanks! :)

  29. Niall Flynn
    July 4, 2013 at 1:02 pm

    Bad approach there I am afraid, you can just replace all your .html with .php without having to change my script.

    Using a .php extension for a native .html doc will affect nothing, HTML will render as per it’s header and all will be fine :)

  30. Roz
    July 5, 2013 at 5:27 pm

    Hi Niall,

    I have a URL like this
    and i want to make it

    can you please provide me the code to make it with htaccess in Godaddy


  31. Niall Flynn
    July 9, 2013 at 1:22 pm

    GoDaddy = SOPA and are by far the lamest host planet wide.

    I would email them as they have there own horrid setup that you will need to use. Sorry I offer no support or anything in relation to GoDaddy.

  32. Azuma-01
    July 18, 2013 at 2:20 am

    Hi Niall,

    I must thanx you for this magic script, it work perfectly until I try
    It fall in a redirection loop. Strangely if the phpfilename is index.php it works.

    An other thing, actully quite strange and almost useless, if the url is “” the /.php is remove and phpfilename is loaded. But in the case that “.php” is a real file and phpfilename a directory, “.php” is unavailable…

    In the same logic, a file named “something.php.php” is also unavailable (both “.php” is removed). But this case may be usefull is you wish to prevent direct access to those files wihtout using heavy security rules.

  33. Niall Flynn
    July 18, 2013 at 2:27 am

    No probs glad to help

  34. Niall Flynn
    July 30, 2013 at 10:48 am

    Handy test area for htaccess here


Leave a comment