10

Here's the directory containing static html files

public
|-- index.html
|-- media
|   `-- blurred_image-8.jpg
|-- post
|   `-- 13considerations
|       `-- index.html

I am attempting to configure nginx to convert all the urls ending with .html to strip out the suffix.

Like this:-

server {
    listen       80;
    server_name  mysite.com;

    location / {
        root   /var/www/mysite/public;
        try_files  $uri  $uri/ $uri/index.html;
    }

    location /media/ {
        alias /var/www/mysite/public/media/;
        error_page 404 = /404;
        expires 30d;
    }

    location /static/ {
        alias /var/www/mysite/public/static/;
        error_page 404 = /404;
        expires 30d;
    }
}

This works properly for the homepage "http://mysite.com/" but if I attempt to access "http://mysite.com/post/13considerations/", I get a 500 internal server error.

What gives?

1 Answer 1

21

The example you're using works for returning the contents of a directory's index.html file, but will not work for files (e.g., http://server/somedir/file will not return the contents of /somedir/file.html).

A simplified configuration, which will return any HTML file without its extension and will use index.html for directories is as follows:

server {
    listen       80;
    server_name  mysite.com;

    index index.html;
    root /var/www/mysite/public;

    location / { 
        try_files $uri $uri/ @htmlext;
    }   

    location ~ \.html$ {
        try_files $uri =404;
    }   

    location @htmlext {
        rewrite ^(.*)$ $1.html last;
    }   
}

How it works:

  • Specifying index index.html will default to using this file when directory URIs are accessed.
  • Putting root outside the location block will apply server-wide.
  • try_files $uri $uri/ @htmlext will look for an exact match for a file or directory first before finally trying to append .html.
  • try_files $uri =404 is to prevent Nginx getting stuck in a rewrite loop if a file can't be found.
  • rewrite ^(.*)$ $1.html last appends .html and restarts the URI matching process.
5
  • 1
    This works very well except for one tiny flaw. If I go to "mysite.com/index.html", it does not redirect to "mysite.com". And only for this particular index.html; for every other url, for example using my original question above, if I visit "mysite.com/post/13considerations/index.html", I do get redirected correctly to "mysite.com/post/13considerations/". Nov 20, 2013 at 10:24
  • is this solution SEO friendly ? Just like the OP I also would like to know how to redirect the root path /index.html file to /
    – Hassan
    Aug 17, 2015 at 9:27
  • 1
    @xperator it's been a while since I wrote the configuration above, but it should serve the contents of /index.html for / on the all directories including the root (e.g., http://example.com/) because of the index index.html statement. Regarding SEO, the above takes the content of the file instead of redirecting, so you could try replacing rewrite ^(.*)$ $1.html last; with rewrite ^(.*)$ $1.html redirect; or rewrite ^(.*)$ $1.html permanent;
    – plasmid87
    Aug 17, 2015 at 10:45
  • On routes which do not have a matching html file, there is a fatal error in Nginx: rewrite or internal redirection cycle while redirect to named location "@htmlext". Is there any way to return a 404 instead?
    – Luca Steeb
    Sep 4, 2021 at 15:19
  • It seems that using break instead of last in the rewrite directive will result in returning a 404 instead of a server error.
    – Luca Steeb
    Sep 4, 2021 at 15:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .