Home

Remove HTML Extension And Trailing Slash In Nginx Config

When you have a static site, sometimes you want to get rid of the HTML extensions and those pesky trailing slashes. Here's how I've done it.

Static websites are back in gaining popularity, even in these days where everything can be driven by a database. With tools like Middleman and Jekyll, web developers have the ability to build fairly complex sites and render them as individual, static files.

I've jumped aboard that train. And while the question as to why I did it deserves its own article, I can say the main motivation for me is speed and cost.

I've been transferring a few of my sites to static files using Middleman. To maintain consistency, I wanted to remove all .html extensions and trailing slashes. And while that's a functional benefit, I also like it better cosmetically.

Remove HTML Extension

There are a few different ways to go about removing the .html extension. I've found the following to work just fine:

server {
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
}

Then we have to make sure Nginx knows what files to look for, and for that we use the try_files directive. We'll look for a file with the current $uri and an .html extension, and if no file exists, we check for a directory with that name and serve the index. Otherwise, we render a 404 error.

server {
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;

index index.html;
try_files $uri.html $uri/ $uri =404;
}

Remove Trailing Slashes

After that first step, we have a URL without a .html extension. However, if the file of interest was an index.html file, it could still be accessed via the name of the parent directory with a trailing slash.

For me, for example, I was getting a URL at https://example.com/page/2/, but I didn't want the trailing slash.

We have to remove the trailing slash after we have removed the .html extension.

The gotcha here is that we have to alter the try_files directive to look for an index.html file first.

server {
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
rewrite ^/(.*)/$ /$1 permanent;

index index.html;
try_files $uri/index.html $uri.html $uri/ $uri =404;
}

Pulling It Together

To pull it all together, I'll share a slightly-altered version of my config for this site.

server {
listen 80;
server_name example.com *.example.com;

rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
rewrite ^/(.*)/$ /$1 permanent;

root /path/to/project/root;
index index.html;
try_files $uri/index.html $uri.html $uri/ $uri =404;

error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
}

A quick thanks to Jason Garber for his note on falling back to $uri within the try_files directive.

Let's Connect

Keep Reading

WTF is HTML?

A brief description of HTML, before suggesting a couple free courses.

Jun 24, 2020

Remove the "www" from a URL with Nginx

For SEO purposes, it's best to choose between www and no www. See how to do it with Nginx.

Dec 27, 2014

Use Netlify as a Shared Asset Host

When you need to share media assets across multiple sites, you can take advantage of tools you’re already using to make that process simple and convenient.

Aug 13, 2022