Append trailing slashes to URLs in Nginx

In this guide, we'll configure Nginx to always append trailing slashes to URLs, improving consistency and avoiding potential duplicate content SEO issues. Plus, we'll cover testing HTTP redirects to ensure everything is working as expected.

When it comes to managing a website, there's a lot to consider - including the impact of trailing slashes on your URLs and how they can affect SEO. While URLs don't have to have trailing slashes, consistency is key to avoiding duplicate content issues. This is especially important when a page is accessible on both URLs with and without trailing slashes, as search engines may treat them as separate pages and dilute your page's search engine ranking. To avoid any confusion, it's recommended to choose a URL structure and redirect URLs accordingly to consolidate their signals.

But what about canonical URLs? While they are effective at preventing duplicate content issues, they may not always be helpful regarding analytics. You can see this firsthand in the Sysadmin For Devs Fathom Analytics dashboard. You'll see the traffic is split, which can make it harder to track user behavior accurately.

Screenshot showing Fathom Analytics dashboardWhile some content management systems like WordPress handle trailing slash redirects automatically, not all do - especially if you're running something custom. In this post, we'll configure Nginx to always add trailing slashes to URLs. Then we'll dive into testing redirects to ensure everything is working smoothly.

Nginx trailing slash rewrite rule

Nginx ships with the ngx_http_rewrite_module module, which allows you to modify request URIs using regular expressions. It's a powerful tool that can be used for tasks such as redirecting URLs or creating user-friendly URLs. To append trailing slashes, we'll make use of the rewrite directive.

Open your site's Nginx virtual host file. Depending on your platform, this will be located differently, but on Debian-based distros, it's typically within /etc/nginx/sites-available/. Here are a few platform-specific examples:

  • Forge: /etc/nginx/sites-available/DOMAIN

  • SpinupWP: /etc/nginx/sites-available/DOMAIN/DOMAIN

Add the following directive within the server block before any location blocks.

rewrite ^([^.]*[^/])$ $1/ permanent;

This will match any URI that doesn't contain a file extension or existing trailing slash. Therefore, /hello-world becomes /hello-world/ and /style.css remains untouched. Query strings will be appended to the new URL by Nginx automatically, so the regex doesn't need to handle them.

Save the changes and verify that your Nginx config is valid:

$ sudo nginx -t

If no issues are reported, go ahead and reload Nginx. Otherwise, you'll want to double-check your changes for any errors.

$ sudo service nginx reload

Testing HTTP redirects

Once you've updated your Nginx config, you should thoroughly test that the redirects are working as intended. When it comes to testing redirect rules, cURL is your friend. Specifically, you'll want to use HEAD requests using the -I flag, which will return the HTTP headers without downloading the entire page.

$ curl -I https://sysadminfordevs.com
HTTP/2 200
server: nginx
date: Wed, 22 Mar 2023 21:29:05 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding

When a redirect is present, a 300 status code will be returned, along with a location header that indicates the redirect destination URL.

$ curl -I https://www.sysadminfordevs.com
HTTP/2 301
server: nginx
date: Wed, 22 Mar 2023 21:29:05 GMT
content-type: text/html; charset=UTF-8
location: https://sysadminfordevs.com/

Here you can see the www subdomain is redirected to the apex domain (sysadminfordevs.com).

As already mentioned, WordPress handles trailing slash redirects out of the box. When a redirect comes from WordPress, the x-redirect-by header is added to the response. This can be useful when tracking down where a redirect is being added. If you were to add the above Nginx rewrite rule to a WordPress site, you wouldn't see the x-redirect-by header because Nginx adds the redirect before the request ever reaches WordPress.

$ curl -I https://www.sysadminfordevs.com
HTTP/2 301
server: nginx
date: Wed, 22 Mar 2023 21:29:05 GMT
content-type: text/html; charset=UTF-8
location: https://sysadminfordevs.com/
x-redirect-by: WordPress

Remember your site's content

It's important to ensure that links within your site's HTML and XML sitemap use the trailing slash to prevent unnecessary redirects. Using the correct URL structure internally ensures that users are directed to the correct page the first time without the overhead of additional redirects. After improving your link consistency for SEO, the last thing you want is to negatively affect users visiting your site by having them jump through unnecessary redirect loops.

Sponsored by DeploymentHawk

Automatically audit your site's vital pages as your site changes. Catch performance, accessibility, and SEO issues before they impact your business. Try for free

Sysadmin tutorials delivered directly to your inbox.