I have been doing a lot of experimenting with my website lately. Recently, I was trying to configure some special rules for my website’s homepage. In Nginx, I wanted to match requests for the homepage only. When I looked in the access log, requests for https://www.tollmanz.com are registered as /. The excerpted headers for the request looks like:

authority: www.tollmanz.com
method: GET
path: /
scheme: https

Given that the path for the homepage is simply /, I added the location to my configuration. A heavily excerpted configuration looked something like:

server {
    listen         443 ssl;
    server_name    www.tollmanz.com;
    root           /path/to/tollmanz.com/;

    # Match homepage
    location = / {}

    # Match assets
    location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2|woff|ttf)$ {}

    # All other files
    location / {}
}

I set up three locations: homepage, assets, and all other files. Nginx docs are very clear that location = / {} would match / over location / {} because it is more specific and should therefore take precedence; however, that absolutely did not work with any amount of trying.

After a ton of searching, I finally stumbled upon the index directive docs. In an aside at the end of the page, it mentions:

It should be noted that using an index file causes an internal redirect, and the request can be processed in a different location… a “/” request will actually be processed in the second location as “/index.html”.

By default, the index directive is set to display the index.html file. Since my site is a Jekyll site, all of the pages are index.html files within a specific directory. When I thought I needed to match /, I actually needed to match /index.html. Since Nginx by default will look for an index.html file inside of a directory request, I had to update my location to specifically match /index.html, even though the logs only suggest that I’m trying to match /. I needed to update my config to:

server {
    listen         443 ssl;
    server_name    www.tollmanz.com;
    root           /path/to/tollmanz.com/;

    # Match homepage
    location = /index.html {}

    # Match assets
    location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2|woff|ttf)$ {}

    # All other files
    location / {}
}

This configuration makes a lot of sense in the end, but it was terribly confusing to work out. I really hope this note-to-self saves someone time in the future.