ReactViteFirebaseVercelDeploymentReact Router

Direct URL Works Locally But Returns 404 After Deployment

The ultimate fix for React Router reload issues on Vercel, Firebase, and Netlify.

K

Khadar Baba

Full Stack & Debugging Engineer

6 min read
Updated 5/21/2026
Urgency: Your React app works perfectly locally. Navigation works. But after deployment, refreshing a page suddenly returns 404 Not Found. This is not a code bug; it is a server configuration issue.Tested against Next.js 14 & Firebase v10 • Last verified May 2026

Quick Answer

This blog fixes the common issue where React or Vite Single Page Applications (SPAs) return a 404 error upon page reload or direct URL access after deployment to Vercel or Firebase. It explains that since SPAs handle routing on the client side, the server must be configured with rewrites to redirect all requests to index.html, allowing the app to handle the sub-routes correctly.

Similar Error Patterns

404 Not Found
The requested URL /dashboard was not found on this server.
Cannot GET /help

Are You Seeing This?

  • Direct URL access returns 404 Not Found after deployment.
  • Page reload in the browser shows a server-side 404 error.
  • Navigation works fine when clicking links, but fails on refresh.
  • Shared links to internal pages (like /profile) don't work for others.

You just deployed your beautiful Vite or React SPA. You click around the navigation links, and everything works perfectly. But then, you refresh the page at `/dashboard` or share a direct link with a friend, and they see it: `404 Not Found`.

This is one of the most frustrating 'it works on my machine' bugs. Locally, your dev server handles these routes effortlessly. In production, the server is looking for a physical file that doesn't exist. Here is how to fix it in 60 seconds.

Quick Fix for 404 on Refresh

  • 1Vercel: Add a vercel.json with rewrites to index.html.
  • 2Firebase: Add a rewrites rule in firebase.json.
  • 3Netlify: Add a _redirects file with /* /index.html 200.
  • 4Next.js: No fix needed if using App Router (it handles this automatically).

Root Causes

SPA Routing vs. Server-Side Lookup

In a Single Page Application (SPA), React Router handles 'navigation' by changing the URL in the browser without actually requesting a new file from the server. However, when you reload, the browser *does* ask the server for `/dashboard`. Since there is no `dashboard.html` file on the server, it returns a 404.

React Router handling

React Router is a client-side library. It only starts working *after* `index.html` has loaded. If the server crashes with a 404 before sending `index.html`, React Router never gets a chance to run.

Step-by-Step Fix Guide

1

The Firebase Fix

Tell Firebase Hosting to redirect all unknown requests to `index.html` so React Router can take over.

// firebase.json
{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
2

The Vercel Fix

Vercel needs a `vercel.json` file in your root directory to handle SPA rewrites correctly for non-Next.js apps.

// vercel.json
{
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/"
    }
  ]
}
3

Wait... What about Next.js?

If you are using the Next.js App Router, you usually do NOT need this. Next.js is a framework that handles routing on the server-side out of the box. This issue primarily affects Vite, Create React App, and standalone React Router DOM setups.

  • If you are seeing 404s in Next.js, it's likely a dynamic route configuration issue, not an SPA rewrite issue.

Still Stuck with 404s?

If you've added the rewrites and it's still not working, your hosting setup might be more complex. I can help you debug your Vite/React deployment pipeline.

Fix My Deployment

Related Errors

  • 404 on Netlify

    Create a file named `_redirects` in your `public` folder with the content: `/* /index.html 200`.

  • Blank page on refresh

    Check if your `base` path in `vite.config.ts` matches your deployment subdirectory.

Prevention Strategy

  • Always add a deployment configuration file (vercel.json, firebase.json) before your first push.
  • Use a deployment checklist that includes 'Direct URL Access' testing.
  • Consider using Next.js if you want full-stack routing handled automatically.

Still Stuck With This Issue?

Send your exact error message or deployment issue. I'll respond with a targeted fix.

Drop screenshots here or browse

PNG, JPG, WebP • Max 5MB • Up to 3 files

Private submission — your data is never shared publicly.

Need a Deeper Fix?

Describe your full project issue below and I'll get back to you with a targeted fix.

Drop screenshots here or browse

PNG, JPG, WebP • Max 5MB • Up to 3 files

Your data is stored securely and never shared with third parties.

Frequently Asked Questions about Direct URL Works Locally But Returns 404 After Deployment (Fix)

Does this affect SEO?

Quick Answer: Yes. If Googlebot tries to crawl a direct link and gets a 404, it won't index that page. Rewriting to index.html with a 200 status code ensures your routes stay indexable.

Can I use HashRouter instead?

Quick Answer: Yes, `HashRouter` (using URLs like `/#/about`) avoids this issue because the server ignores everything after the `#`. However, it's generally considered bad for SEO and modern UX.

ServicesStudent ProjectsBlogContact
Chat with an Expert