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/". Commented 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 / Commented 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; Commented 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? Commented 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. Commented Sep 4, 2021 at 15:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.