Pages return 404 with or without a trailing slash
Why /about/ works and /about does not, or the other way round, and one fix that works on any platform.
By Frontsiter · Published · 2 min read
The problem
After you deploy, some links break. /about/ shows the page but /about returns 404 Not Found, or the other way round. It worked on your computer, because development servers accept a URL with or without a trailing slash.
Why it happens
/about and /about/ are two different URLs, and something between the browser and your page handles only one of them. On a static site, the web server looks for a matching file: if the build wrote about.html, there is no file or folder for /about or /about/. In an app or a CMS, a route or a server rule matches one form and not the other.
The fix
1. Redirect at the web server. Add the rule for your server. It redirects page URLs without a trailing slash to the same URL with one, keeps the query string, and leaves alone real files (such as style.css), URLs with an extension (such as Magento's product.html), and form submissions (POST requests).
Apache or LiteSpeed, in .htaccess before any other rewrite rules:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(GET|HEAD)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.[^/]*$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^ %{REQUEST_URI}/ [R=301,L]Nginx, inside the server block:
set $add_slash "";
if ($request_method ~ ^(GET|HEAD)$) { set $add_slash "m"; }
if ($uri ~ "^(.*/)?[^/.]+$") { set $add_slash "${add_slash}u"; }
if (!-f $request_filename) { set $add_slash "${add_slash}f"; }
if ($add_slash = "muf") { return 301 $uri/$is_args$args; }2. Make sure the slash form loads. On a static site, build each page as a folder with an index.html inside: trailingSlash: true in Next.js, trailingSlash = "always" in SvelteKit; Astro and Nuxt do it by default. In a CMS, use URLs that end in a slash, for example a WordPress permalink structure that ends in /. If your platform redirects the other way, to the form without the slash, the two redirects loop.
3. Link with the trailing slash everywhere. Write /about/ in your links, sitemap, and canonical tags, so each page has one address.
Check that it is fixed
- On the live site: open
/about. It redirects to/about/with a 301, and the page loads. - Files and forms: a stylesheet, an image, and a form submission still work, with no redirect.
Frontsiter avoids this problem on Apache shared hosting with trailingSlash: true, so every page is built as a folder with an index.html inside.
