Not found errors
404 when you refresh a page or open a link to it
The home page works and clicking around works, but refreshing a page like /about, or opening a link to it, gives a 404.
Checked 16 October 2026
The short answer
Your app routes in the browser, so /about has no file of its own on the server. Tell the host to serve index.html for paths it can't find, and the app takes it from there.
Find your cause
4 causes, most likely first
- 1
There's no fallback to index.html
How to tell: It's a single-page app (React Router, Vue Router, Angular) and only deep links and refreshes fail.
Fix
Add the fallback for your host, below.
- 2
The fallback file isn't in the deployed site
How to tell: You added
_redirectsorvercel.json, but nothing changed.Fix
netlify.tomlandvercel.jsonbelong at the root of the repository; a_redirectsfile has to end up in the publish folder, so put it inpublic/. Commit them: a file that's ignored by git never reaches the host. - 3
A top-level 404.html on Cloudflare Pages
How to tell: Your build output has a
404.htmlat the top.Fix
Cloudflare Pages only falls back to your app when there's no top-level
404.html. Remove it from the build output. - 4
Or avoid the problem altogether
How to tell: You'd rather not depend on a host setting.
Fix
A hash router (/#/about) never asks the server for /about, so it works anywhere. Building each page to its own HTML file (Astro, a Next.js export, SvelteKit with prerendering) works anywhere too, and suits search engines best.
Per host
The fallback for your host
99helpers
Copy index.html to 404.html in your build folder before you drop it (cp dist/index.html dist/404.html). 99helpers serves 404.html for any path without a file, so the app opens and routes from there.
GitHub Pages
Copy index.html to 404.html as a step in the workflow, after the build. GitHub Pages serves 404.html for unknown paths, so the app opens (with a 404 status).
- name: Open the app for any path
run: cp dist/index.html dist/404.htmlNetlify
Add a redirect rule with status 200, which serves index.html without changing the address. Or put a _redirects file with the line /* /index.html 200 in your public/ folder.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Vercel
Add a rewrite in vercel.json at the root of the repository, and commit it.
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}Cloudflare Pages
Nothing to add: without a top-level 404.html, Cloudflare Pages serves your home page for any unknown path. If your build makes a 404.html, leave it out.
Questions
Also asked
Is the 404.html trick bad for search engines?
On GitHub Pages the page opens, but with a 404 status, so search engines may leave those addresses out. If search matters, build each page to its own file, or use a host with real rewrites.
Why does it work with npm run dev?
The dev server already sends every unknown path to index.html. Static hosts don't, until you tell them to.
Rather skip build settings altogether?
Build on your computer, where it already works, and drop the folder on 99helpers. The site gets its own address, so there's no base path, workflow or build log to get wrong, and it's online in seconds.
Or skip the setup
Drop it in. It's online in seconds.
A file, a folder or a whole site: 99helpers puts it online at its own address, with no git, no build settings and no DNS to start with. Add your own domain whenever you're ready.