Solving 404 errors with client-side routing in React applications on Netlify

René Kulik on 19.09.2024

Introduction

Deploying a React application is usually straightforward, especially when using modern platforms like Netlify. However, there are common routing issues you might face after deployment, especially when using client-side routers such as TanStack Router, React Router, or others.

One such issue is navigating to a subpage and then refreshing the browser, only to be greeted by a 404 page. If you’re experiencing this issue, you’re not alone! In this blog post, I’ll explain how you can solved this issue when deploying your site on Netlify.

The problem: 404 errors on page reload

If you’re working with a Single Page Application (SPA) using client-side routing, like React paired with TanStack Router, you’ll notice that everything works perfectly during local development. You can navigate to different pages without encountering any issues. However, once deployed to Netlify, a strange problem might occur:

When you navigate to a page (e.g., /about) and reload the page, Netlify serves its default 404 error page:

404 error page

This can be frustrating, especially when the routes work just fine while using internal links to navigate between pages.

Why this happens in client-side routing

This issue arises because of how SPAs handle routing. In an SPA, routes are managed on the client-side (in your browser) rather than on the server. When you navigate to /about, for example, the browser doesn’t request /about from the server. Instead, your React application intercepts the request and dynamically renders the appropriate component for that route.

But when you refresh the page or directly visit a route like /about, the browser makes a direct request to the server for /about. Without the proper configuration, Netlify doesn’t know how to serve that route and instead throws a 404 error because it expects that route to exist on the server (but it doesn’t, since it’s a client-side route).

The solution: Using the netlify.toml file

The solution is simple: we need to tell Netlify to serve our index.html file for every route. This ensures that Netlify serves our application no matter what route is requested, allowing the client-side router to take over and display the correct content.

Enter the netlify.toml file

To fix this issue, you can create a configuration file called netlify.toml at the root of your project. This file is used to configure various settings for your Netlify site, including redirect rules.

Here’s the content of the netlify.toml file to solve this problem:

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

How the redirect rule works

With this in place, when you reload a page like /about, Netlify will serve the index.html file, and your application (and your client-side router of choice) will take care of loading the correct page dynamically.

Conclusion

Handling routing in a Single Page Application deployed on Netlify can be tricky, especially if you’re using client-side routing libraries. The key is to configure Netlify properly to serve the index.html file for all routes, allowing your React applicaton to manage the routing internally.

By adding a netlify.toml file with a redirect rule, you can ensure that your routing works as expected even when users refresh a page or directly visit a specific route.