Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How would I remove all .html extensions as well as any occurrences of index.html from a url string in Nginx

http://www.mysite/index.html to http://www.mysite http://www.mysite/articles/index.html to http://www.mysite/articles http://www.mysite/contact.html to http://www.mysite/contact http://www.mysite/foo/bar/index.html to http://www.mysite/foo/bar

EDIT: Here is my conf file:

server {

    listen 80;

    root /var/www/;
    index  index.html index.htm;

    access_log /var/log/nginx/ spiegle;

    #error_page 404         /404.html;
    #error_page 500 503     /500.html;

    rewrite ^(.*/)index\.html$ $1;
    rewrite ^(/.+)\.html$ $1;

    rewrite ^(.*/)index\.html$ $scheme://$host$1 permanent;
    rewrite ^(/.+)\.html$ $scheme://$host$1 permanent;

    location / {
            rewrite ^/about-us /about permanent                                                                                      
            rewrite ^/contact-us /contact permanent;  

            try_files  $uri.html  $uri/ /index.html;


share|improve this question
I believe it's something like rewrite index.html -; and rewrite .html$ -; but I don't use nginx, so I'm not sure. Hopefully someone can wander along and write a good generic "Nginx Rewrite" Answer so we can have a close target. =] – Chris S Oct 16 '12 at 20:43
The final path of "try_files" directives will create an internal redirect back to the index.html that you are wanting to redirect away from. As far as I can tell from what you are doing, the final "path" should be set to "=404" to generate a 404 if the file doesn't exist. Remove the first block of 2 rewrites so you just have the "permanent" ones, and then switch try_files to: try_files $uri.html "${uri}index.html" =404; – emsearcy Oct 23 '12 at 7:33
up vote -1 down vote accepted

As a rewrite (pass stripped URL to filesystem/backend without changing URL shown to client):

rewrite ^(.*/)index\.html$ $1;
rewrite ^(/.+)\.html$ $1;

Alternatively you can do a 301 redirect (client makes new request):

rewrite ^(.*/)index\.html$ $scheme://$host$1 permanent;
rewrite ^(/.+)\.html$ $scheme://$host$1 permanent;
share|improve this answer
That should go inside of a location / {}? – Pardoner Oct 16 '12 at 21:44
@Pardoner rewrite module's context is server, location and if. You can put them in any one of them. See manual for more – Grumpy Oct 16 '12 at 22:04
I get a 500 error when I use those :( – Pardoner Oct 16 '12 at 22:06
@Pardoner as Peter says they can be used there. Regarding your config, those are two alternatives, not something you should put both of in. If you are unsure which is appropriate for your application, I recommend the 301 redirect. – emsearcy Oct 23 '12 at 7:08
My comment above probably isn't clear. What I mean is that you should only use 2 of my lines from my answer, not all 4. – emsearcy Oct 23 '12 at 7:38

The accepted answer didn't seem to work for me. I'm an apache guy who's making the switch, so this may not work 100% in all circumstances, but this seemed to work on my site (static html pages, just a test):

index index.html;
error_page 404 404.html;
rewrite ^(/.+)\.html$ $1;
try_files $uri.html $uri/ =404;

That is making this happen:

  • url => file it's accessing
  • => index.html
  • => somepage.html
  • => 404.html

Hopefully this'll help out other confused former apache-ists.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.