React + Vite + createBrowserRouter: Production 404 on Nested Routes

In my React + Vite project using createBrowserRouter, everything works as expected in local dev and Vercel preview deployments. But in production, routes like /reset-password and nested paths like /users/:id throw a 404 error when accessed directly or refreshed.

Current (Production only):

  • Visiting /reset-password or any nested route directly causes a Vercel 404 error.
  • Supabase password reset link (which redirects to /reset-password) fails in production.

Expected:

  • These routes should be handled by the SPA (index.html) and routed correctly by React Router.

vite.config.ts

export default defineConfig(({ mode }) => ({
  base: '/',
  server: {
    host: "::",
    port: 8080,
  },
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
}));

vercel.json

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

Steps to reproduce:

  1. Deploy to Vercel
  2. Visit https://your-production-domain/reset-password → :cross_mark: 404
  3. Visit https://your-production-domain/sub-route/:param → :cross_mark: 404
  4. These same URLs work in dev and preview

Project Info

  • Framework: React (TypeScript) + Vite
  • Router: React Router DOM (createBrowserRouter)
  • Hosting: Vercel (Preview works fine, Production has issue)
  • Auth: Supabase (sends email reset-password links to frontend)
  • Deployment: Auto from GitHub
1 Like

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.

1 Like

If you set the framework in your build settings to Vite and remove the rewrites in the vercel.json this should work out of the box

Here’s a deployed example of createBrowserRouter running on Vercel

Let me know if that works for you, otherwise if you share your repo or a minimal reproduction I can debug further

1 Like

Hello Jacob. I am having the same issue with getting 404 when I refresh my nested routes. I went to your live site in your github readme. I am seeing 404 error when refreshing a nested route on your live site. https://vite-react-drab-two-60.vercel.app/

1 Like

@jacobparis Your example site is not working. For example, visit a URL directly instead of from the main page:

https://vite-react-drab-two-60.vercel.app/about

(This is because Vite creates an SPA.)

@kjasmita-microbinio I find it very interesting that it works in preview but not production. Do you have the source code (or a minimal source code with the same error) public anywhere so I can test it?

@bestcodes i added the vercel.json file to the root but it is not fixing the 404 error. Here is my project if you would like to check it out. GitHub - JacobBaqleh1/ROAM

1 Like

@jacobbaqleh1 @kjasmita-microbinio
I found the problem. There is a typo in your vercel.json.

You file should look like this:

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

Diff:

{
  "rewrites": [
    {
-     "src": "/(.*)",
+     "source": "/(.*)",
      "destination": "/index.html",
-     "status": 200
    }
  ]
} 

Working demo:

(This link will no longer be available in a few days):

Please note: The community page doesn’t work on my demo because it requires auth environment variables that only you have.

@bestcodes thanks. I made the edit but I am still getting the 404 error on refresh.

1 Like

Hey @jacobbaqleh1 have your read through our docs for Vite SPAs?

Are you just refresing on the homepage or a particular route/flow?

1 Like

Edit: This response is not applicable to you, ignore it!

Response @jacobbaqleh1 Odd that you are still having issues, since my demo deployment is working fine. Have you modified any of the project settings on the Vercel deployment? Mine look like this:


(All the settings are just the default ones.)

Sorry!

@jacobbaqleh1 I actually think it’s an issue with your setup. Your vercel.json should be in your project root. If you are deploying Develop the folder as the project and using the client subdir for the build output, that isn’t going to find your vercel.json.

Can you move it to the root dir?

1 Like

@miguelcabs Ah, good point! You just made me realize something!


Old solution

This solution is outdated because the project config for your project is different than I assumed.

@jacobbaqleh1 and @kjasmita-microbinio, this is how you should deploy the client to Vercel:

  1. In project settings on vercel.com, use the Vite framework preset and set the root directory to Develop/client:

  2. In Develop/client, (not the GitHub project root), put the vercel.json file. You have already done this:

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

Do not put the vercel.json in the GitHub project root. If you do, you will see a warning:
image
“Provided root directory” means the project root you set in settings on vercel.com, which you should set to Develop/client.


Based on your current project config, you should move vercel.json from Develop/client to Develop/. Do not move it to the GitHub project root, just to Develop/, which is the deployment root.

Try setting “cleanUrls” to “false” in vercel.json

Solution in topic here: Rewrite to index.html ignored for React + Vite SPA (404 on routes)

@miguelcabs @bestcodes Thanks. Moving the vercel.json file to the root dir worked! Appreciate the help.

2 Likes

@jacobbaqleh1 Awesome!

Would you like me to unpublish my copy of your website that I created for demo purposes?
https://vcvm-roam-client.vercel.app/

Edit: I have unpublished my clone of the site.

2 Likes

@bestcodes i dont mind what you do with it

1 Like

The problem had to do with DNS and redirect settings.

2 Likes

3 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.