thinkingincode.ninja [Dark]

How I removed the .html file suffix in site URLs

So, I had a thought the other day. Is there a way to make it so that URLs for my site don't require a .html suffix/file ending? Making it optional sure would be nice, as it would let me clean up the URLs a bit, and make it slightly nicer looking. It's not a huge deal, just a small detail, but I thought it'd be cool to do. And it turns out it's very easy to do in nginx.

A quick Google search led me to the nginx directive try_files. Basically, nginx looks for files in certain locations, and try_files helps control where it looks. The root directive controls the document root, where nginx will try to find a file. Say that root is set to /usr/share/nginx/html; if a request comes in for /my/file.html, nginx will look for a file in /usr/share/nginx/html/my/file.html.

The try_files directive lets you have more control over this process. I believe the default is (based on the fact that this is how it worked without me having the directive set) try_files $uri $uri/;; this tells nginx to first look for the URI as a file, then to look for it as a directory. As a real example, on my site there is a folder /tags, which contains, amongst other things, /tags/index.html. When a request comes in for /tags, nginx first looks for a file $DOC_ROOT/tags, then it will look for $DOC_ROOT/tags/, which will in turn be valid because it will find the index file $DOC_ROOT/tags/index.html (where $DOC_ROOT is the actual location of my HTML documents, which is irrelevant in this example).

Using this information, I tried try_files $uri $uri/ $uri.html;, which worked. What I am telling nginx to do is first look for an exact match for the request URL, then look for it as a directory, and finally try looking for it as a .html file. This means that an HTTP request for /tags/nginx will resolve, because there is a file $DOC_ROOT/tags/nginx.html.

I added this to each of the site server configurations, adding it to the root location directive, like so (this is inside of the server configuration). This applies that file matching scheme for any documents requested under /, so every document on my site.

location / {
    try_files $uri $uri/ $uri.html;
}

That was an easy addition to make for a quick and subtle improvement. Expect to see links generated without the HTML suffix over the next few days (I have to make modifications to the generator scripts to remove the HTML suffix, but it's not high priority).