React Router and Vite App: 404 Error for Routes on Vercel Deployment

I’m deploying a React application built with Vite and using React Router for client-side routing. While the app works perfectly in development, I’m encountering issues when trying to access routes directly after deployment on Vercel. Here’s a summary of the problem:

Problem Description:

  • The app’s root URL (https://manixh.vercel.app/) works fine and I can navigate between pages using the links.

  • However, when I try to access a route directly (e.g., https://manixh.vercel.app/projects), I get a 404: NOT_FOUND error.

App Details:

Built using Vite with React.
Using React Router for client-side routing with .
Routes in App.jsx are defined like this:

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/projects" element={<Projects/>} />
    <Route path="/blogs" element={<Blogs/>} />
  </Routes>
</BrowserRouter>

What I Tried:

  1. Added a vercel.json file with the following content:
{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
  1. Verified the vite.config.js file and ensured the build output is correct.
  2. Previewed the app locally after running npm run build and npm run preview, and it works fine.

Expected Behavior:

Routes like /projects or /blogs should be handled by React Router and render the respective components.

Actual Behavior:

Directly accessing any route other than / results in a 404: NOT_FOUND error.

Could anyone guide me on the correct way to configure Vercel for a Vite app with React Router? Any help would be greatly appreciated!

There’s another community post with 404 debugging tips that might be helpful. Please give these solutions a try and let us know how it goes.

A human should be around soon to offer more advice. But you can also get helpful information quickly by asking v0.

Hey, @ig-imanish!

Thanks for your patience. :smiley:

Could you perhaps try using this more explicit configuration?

{
  "routes": [
    { "handle": "filesystem" },
    { "src": "/.*", "dest": "/index.html" }
  ]
}

Or alternatively, stick with rewrites but be more specific:

{
  "rewrites": [
    { "source": "/((?!api/.*).*)", "destination": "/index.html" }
  ]
}

Let us know how you get on!

Hi Pauline, I’m experiencing the same issue, and these options don’t work for me.

Hey and welcome to the community, Stoplightdev! :waving_hand:

Happy to help - can you share any more information with us?

I also recommend checking out: Debugging 404 Errors