How to Fix 404 Error on Vercel with React Router and Client-Side Routing

When deploying React applications to Vercel, you may encounter a frustrating issue where direct URLs like /about or /contact result in a 404 page. This happens because Vercel serves static files by default, and when you try to access a route that doesn't correspond to a file on the server, it returns a 404 error. In this article, I'll walk you through how I encountered this issue, the steps I took to resolve it, and how you can fix this in your own React app deployed on Vercel. Intro React applications that use React Router for client-side routing can run into problems when deployed to static hosting services like Vercel. Since Vercel serves files based on URLs, it expects an actual file to be found at every URL you access. However, in a single-page application (SPA) like a React app, the routing is handled by JavaScript running on the client-side, and no physical files exist for routes like /about, /contact, etc. This causes a 404 error if you try to directly access these URLs. How I Came to Know About the Issue When I deployed my React app on Vercel, I encountered an issue where navigating directly to a route such as https://your-app.vercel.app/about or refreshing the page would show a 404 error. Initially, everything worked fine during development and in the browser when navigating between pages. However, once I uploaded the app to Vercel, directly entering a URL or refreshing the page led to an error, as Vercel was trying to find an actual file at the given path and couldn’t find anything. This issue wasn’t related to React or React Router itself. It stemmed from the way Vercel serves static files and doesn’t know how to handle dynamic routes like those used in SPAs. Steps to Solve the Issue Identify the Problem: The root cause of this issue lies in how static hosting services like Vercel serve files. When you access a URL like /about, Vercel looks for a physical file that matches that URL path, such as /about.html. However, in a React SPA, routes are handled entirely by JavaScript and React Router, and there are no physical files corresponding to the routes. Understand the Solution: We need to tell Vercel to redirect all routes to the index.html file. This allows React Router to take over and handle the routing on the client side, ensuring that the correct component is rendered when you visit a route. Set Up a Rewrite Rule: The solution involves adding a rewrite rule that ensures every URL, whether it’s /about, /contact, or any other route, is routed to the index.html file. Once the index.html file is loaded, React Router will handle the rest. Solution To fix this, you need to configure Vercel to handle client-side routing correctly by redirecting all paths to the index.html file. Here's how you can achieve that: Option 1: Using vercel.json Configuration Create a vercel.json File: In your project’s root directory, create a vercel.json file with the following content: { "rewrites": [ { "source": "/:path*", "destination": "/index.html" } ] } What This Does: rewrites: This rule tells Vercel to rewrite all URLs (specified by :path*) to point to the index.html file. source: "/:path*": This matches any URL path, including paths like /about, /contact, and /locations. destination: "/index.html": This ensures that no matter what route is accessed, Vercel serves the index.html file, allowing React Router to take control. Deploy Changes: Once you've added this vercel.json file to your project, commit and push the changes to your repository. Vercel will automatically redeploy your app with the new configuration. Option 2: Using Vercel’s Dashboard for Redirects Alternatively, you can set up redirects and rewrites directly through Vercel’s dashboard: Go to your Vercel Dashboard. Under Settings, find the Redirects/Rewrites section. Add a new Rewrite rule with the following configuration: Source: /:path* Destination: /index.html Type: 200 (Rewrite) This accomplishes the same result without needing a vercel.json file. Conclusion By default, Vercel serves files based on their URL path, which can lead to 404 errors when you try to access routes like /about or /contact in a React app that uses React Router. The solution is simple: configure Vercel to redirect all routes to the index.html file, allowing React Router to handle the client-side routing. With this setup, your app will work seamlessly both when users navigate between pages within the app and when they refresh or directly access routes via URL. This is a common issue faced by React developers deploying SPAs to Vercel, and now you have a clear, actionable solution to fix it. Bonus Tips: If you use other static hosting services like Netlify or GitHub Pages, the solution for handling client-side routing is similar, and these services provide their own configuration methods (like _re

Apr 27, 2025 - 15:53
 0
How to Fix 404 Error on Vercel with React Router and Client-Side Routing

When deploying React applications to Vercel, you may encounter a frustrating issue where direct URLs like /about or /contact result in a 404 page. This happens because Vercel serves static files by default, and when you try to access a route that doesn't correspond to a file on the server, it returns a 404 error. In this article, I'll walk you through how I encountered this issue, the steps I took to resolve it, and how you can fix this in your own React app deployed on Vercel.

Intro

React applications that use React Router for client-side routing can run into problems when deployed to static hosting services like Vercel. Since Vercel serves files based on URLs, it expects an actual file to be found at every URL you access. However, in a single-page application (SPA) like a React app, the routing is handled by JavaScript running on the client-side, and no physical files exist for routes like /about, /contact, etc. This causes a 404 error if you try to directly access these URLs.

How I Came to Know About the Issue

When I deployed my React app on Vercel, I encountered an issue where navigating directly to a route such as https://your-app.vercel.app/about or refreshing the page would show a 404 error. Initially, everything worked fine during development and in the browser when navigating between pages. However, once I uploaded the app to Vercel, directly entering a URL or refreshing the page led to an error, as Vercel was trying to find an actual file at the given path and couldn’t find anything.

This issue wasn’t related to React or React Router itself. It stemmed from the way Vercel serves static files and doesn’t know how to handle dynamic routes like those used in SPAs.

Steps to Solve the Issue

  1. Identify the Problem:
    The root cause of this issue lies in how static hosting services like Vercel serve files. When you access a URL like /about, Vercel looks for a physical file that matches that URL path, such as /about.html. However, in a React SPA, routes are handled entirely by JavaScript and React Router, and there are no physical files corresponding to the routes.

  2. Understand the Solution:
    We need to tell Vercel to redirect all routes to the index.html file. This allows React Router to take over and handle the routing on the client side, ensuring that the correct component is rendered when you visit a route.

  3. Set Up a Rewrite Rule:
    The solution involves adding a rewrite rule that ensures every URL, whether it’s /about, /contact, or any other route, is routed to the index.html file. Once the index.html file is loaded, React Router will handle the rest.

Solution

To fix this, you need to configure Vercel to handle client-side routing correctly by redirecting all paths to the index.html file. Here's how you can achieve that:

Option 1: Using vercel.json Configuration

  1. Create a vercel.json File: In your project’s root directory, create a vercel.json file with the following content:
   {
     "rewrites": [
       {
         "source": "/:path*",
         "destination": "/index.html"
       }
     ]
   }
  1. What This Does:

    • rewrites: This rule tells Vercel to rewrite all URLs (specified by :path*) to point to the index.html file.
    • source: "/:path*": This matches any URL path, including paths like /about, /contact, and /locations.
    • destination: "/index.html": This ensures that no matter what route is accessed, Vercel serves the index.html file, allowing React Router to take control.
  2. Deploy Changes:
    Once you've added this vercel.json file to your project, commit and push the changes to your repository. Vercel will automatically redeploy your app with the new configuration.

Option 2: Using Vercel’s Dashboard for Redirects

Alternatively, you can set up redirects and rewrites directly through Vercel’s dashboard:

  1. Go to your Vercel Dashboard.
  2. Under Settings, find the Redirects/Rewrites section.
  3. Add a new Rewrite rule with the following configuration:
    • Source: /:path*
    • Destination: /index.html
    • Type: 200 (Rewrite)

This accomplishes the same result without needing a vercel.json file.

Conclusion

By default, Vercel serves files based on their URL path, which can lead to 404 errors when you try to access routes like /about or /contact in a React app that uses React Router. The solution is simple: configure Vercel to redirect all routes to the index.html file, allowing React Router to handle the client-side routing.

With this setup, your app will work seamlessly both when users navigate between pages within the app and when they refresh or directly access routes via URL. This is a common issue faced by React developers deploying SPAs to Vercel, and now you have a clear, actionable solution to fix it.

Bonus Tips:

  • If you use other static hosting services like Netlify or GitHub Pages, the solution for handling client-side routing is similar, and these services provide their own configuration methods (like _redirects file for Netlify).
  • Always test your app in different scenarios—local development, direct navigation, and page refreshes—after deploying to catch any potential issues early.

If you found this article helpful, don't forget to share it with others in the React community!