Have trailing slash problems after deploying a static website in production?
This repo explains factually the behavior of:
We also suggest some possible solutions
Let's get more familiar with trailing slash issues.
Common problems:
- SEO/perf issues: when browsing
/myPath
, your host redirects to/myPath/
- 404 issues: relative link such as
<a href="otherPath">
are resolved differently (/otherPath
or/myPath/otherPath
depending on the presence/absence of a trailing slash - UX issues: your host adds a trailing slash, and later your single-page-application frontend router removes it, leading to a confusing experience and flickering url
Causes:
- static site generators can emit different files for the same path
/myPath
:/myPath.html
or/myPath/index.html
(the later can lead to an additional trailing slash) - host providers all have a different behavior when serving static files, there is no standard
Considering this static site:
static
│
├── file.html
│
├── folder
│ └── index.html
│
├── both.html
└── both
└── index.html
Behavior of various static hosting providers:
Host | Settings | Url | /file | /file/ | /file.html | /folder | /folder/ | /folder/index.html | /both | /both/ | /both.html | /both/index.html |
---|---|---|---|---|---|---|---|---|---|---|---|---|
GitHub Pages | link | ✅ | 💢 404 | ✅ | ➡️ /folder/ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
Netlify | Default | link | ✅ | ➡️ /file | ✅ | ➡️ /folder/ | ✅ | ✅ | ✅ | ➡️ /both | ✅ | ✅ |
Netlify | Pretty Urls on | link | ✅ | ➡️ /file | ✅ | ➡️ /folder/ | ✅ | ✅ | ✅ | ➡️ /both | ✅ | ✅ |
Netlify | Pretty Urls off | link | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Vercel | Default | link | 💢 404 | 💢 404 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Vercel | cleanUrls=false trailingSlash=undefined | link | 💢 404 | 💢 404 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Vercel | cleanUrls=false trailingSlash=false | link | 💢 404 | 💢 404 | ✅ | ✅ | ➡️ /folder | ✅ | ✅ | ➡️ /both | ✅ | ✅ |
Vercel | cleanUrls=false trailingSlash=true | link | 💢 404 | 💢 404 | ✅ | ➡️ /folder/ | ✅ | ✅ | ➡️ /both/ | ✅ | ✅ | ✅ |
Vercel | cleanUrls=true trailingSlash=undefined | link | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Vercel | cleanUrls=true trailingSlash=false | link | ✅ | ➡️ /file | ➡️ /file | ✅ | ➡️ /folder | ➡️ /folder | ✅ | ➡️ /both | ➡️ /both | ➡️ /both |
Vercel | cleanUrls=true trailingSlash=true | link | ➡️ /file/ | ✅ | ➡️ /file/ | ➡️ /folder/ | ✅ | ➡️ /folder/ | ➡️ /both/ | ✅ | ➡️ /both/ | ➡️ /both/ |
Cloudflare Pages | link | ✅ | ➡️ /file | ➡️ /file | ➡️ /folder/ | ✅ | ➡️ /folder/ | ✅ | ✅ | ➡️ /both | ➡️ /both/ | |
Render | link | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
Azure Static Web Apps | link | ✅ | ➡️ /file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Let's keep this resource up-to-date, and make it exhaustive together.