React: Handling 404 Errors on Netlify Deployments ( A Step-by-Step Guide with React, Vite, and react-router-dom)

Signor Dev
6 min readDec 16, 2023
Netlify page not found

In one of my previous articles, I talked about the 404 error on Vercel deployment and how to resolve it. In this article, we are going to explore how to resolve this similar error on Netlify.

Deploying single-page applications (SPAs) to production environments wherein client-side routing was used can be challenging at times. Error 404 (Page not found) is one of them. This error occurs when users try to access a specific route directly or refresh the page.

How to Resolve this Issue

First, we’ll start by setting up a React project using Vite(a blazing-fast build tool), and then dive into adding client-side routing using react-router-dom. Finally, we’ll tackle the 404 error issue head-on and show you how to resolve it with Netlify’s redirects.

Setting Up a React Project with Vite:

  1. Install Node.js and npm on your machine if you haven’t already.
  2. Open your terminal and navigate to the directory where you want to create your project.
  3. Run the command npm init vite@latest to create a new Vite project. This will prompt you to enter a project name and select a framework and variant. Choose "React" as the framework and "JavaScript" as the variant.
  4. Once the project is created, navigate to the project directory and run npm install to install the project dependencies.
  5. Finally, run npm run dev to start the development server. Your React app should now be running at http://localhost:5173.

Adding Routing with react-router-dom:

React offers a fantastic library for handling routing called react-router-dom. In this section, we'll integrate react-router-dom into our React project created with Vite.

Before we can begin using react-router-dom, we need to install it as a project dependency. Open your terminal and run the following command within your Vite-based React project directory:

npm install react-router-dom

This command will download and install the necessary packages to enable routing in our application.

Furthermore, to get started with react-router-dom, we'll first define a basic routing structure. This typically involves creating different components for various pages or views and configuring routes for them.

Example, we can have this 👇 in our App component.

// src/App.jsx

import { BrowserRouter as Router, Routes, Route} from 'react-router-dom';
import Home from './components/Home';
import Contact from './components/Contact';
function App() {
return (
<Router>
<Routes>
<Route path="/" exact element={<Home/>} />
<Route path="/contact" element={<Contact/>} />
</Routes>
</Router>
);
}
export default App;

Now that we’ve set up the routing structure in the App component, let’s create the components for our home and contact pages. These components will be displayed when the user navigates to the respective URLs.

Below is an example of what the Home.jsx and Contact.jsx components might look like:

// src/components/Home.jsx

const Home=()=> {
return (
<div>
<h1>Welcome to the Home Page</h1>
{/* Add your home page content here */}
</div>
);
}
export default Home;
// src/components/Contact.jsx

const Contact=()=> {
return (
<div>
<h1>Contact Us</h1>
{/* Add your contact page content here */}
</div>
);
}
export default Contact;

With these components in place, we now have a basic routing structure for our SPA. When a user navigates to the root URL (‘/’), they will see the content of the Home component, and when they navigate to '/contact', they will see the content of the Contact component.

To enable navigation between routes, you can use Link components from react-router-dom. For example, you can add a navigation menu to your application like this:

// src/components/Navigation.jsx
import { Link } from 'react-router-dom';

const Navigation=()=> {
return (
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
</nav>
);
}
export default Navigation;

We can now import this Navigation component into our App.jsx component to provide users with an easy way to navigate between different views.

// src/App.jsx

import { BrowserRouter as Router, Routes, Route} from 'react-router-dom';
import Home from './components/Home';
import Contact from './components/Contact';
import Navigation from './components/Navigation';
function App() {
return (
<Router>
<Navigation/>
<Routes>
<Route path="/" exact element={<Home/>} />
<Route path="/contact" element={<Contact/>} />
</Routes>
</Router>
);
}
export default App;

With react-router-dom integrated into your project, you now have a powerful tool for managing client-side routing in your React SPA.

However, there’s one crucial challenge that remains, which is handling the dreaded 404 error when deploying to Vercel.

The 404 Error Issue

This error occurs when a user tries to access a specific route directly or refreshes the page. In traditional server-rendered applications, the server handles route requests and serves the corresponding HTML pages. But in SPAs, routing is managed on the client-side, and the server may not be aware of these client-side routes. This discrepancy results in the server returning a “Page Not Found” error for direct route accesses, causing frustration for users and confusion for developers.

Using Netlify Redirects

Netlify, our preferred deployment platform, provides a solution to this problem through its redirects and rewrites functionalities. This allows us to configure how incoming requests to our application’s URLs should be handled. With the right rewrite and redirect rules, we can ensure that all requests are redirected to the root URL, preventing the 404 error from occurring.

Procedures :

  1. Create a netlify.toml File:

To define our rewrite rules, we need to create a netlify.toml file in the root directory of our project.

// netlify.toml

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

In the above code, we defined a simple rewrite rule:

  • [[redirects]] defines a section for specifying redirects and rewrites. It's a Netlify-specific configuration that allows you to control how the server handles incoming requests.
  • from = "/*" defines the pattern for matching incoming requests. In this case, /* matches any path requested on your deployed site.
  • to = "/index.html" specifies the target destination for all the matched requests. It tells the server to serve the index.html file for any URL that matches the specified pattern.
  • status = 200 sets the HTTP status code for the redirect response. In this case, it's set to 200 (OK), indicating that the request was successful. This is crucial for client-side routing to work correctly because it ensures that the server responds with a success status code for all paths, allowing the React app to handle the routing on the client-side.

How It works

When a visitor accesses any URL on your deployed website, the configuration in the netlify.toml file tells the server to direct all requests, regardless of the URL path, to the index.html file. This means that whenever someone visits a specific page or URL within your site, the server responds by serving the main index.html file instead of showing a "Page Not Found" error.

As a result, your React application’s main entry point is always served, allowing React Router to take control. React Router then manages the URL paths on the client-side, rendering the appropriate components and pages based on the requested URL. This setup ensures a seamless navigation experience within your React application on Netlify, eliminating any issues related to “Page Not Found” errors.

2. Deploy to Netlify:

Now that the rewrite rule has been configured, we can deploy our application to Netlify. You can do this by linking your Netlify account to your Git repository.

a. Connect GitHub to Netlify:

  • Go to your Netlify dashboard (https://app.netlify.com).
  • Click on the “New site from Git” button.
  • Choose GitHub as your Git provider and follow the prompts to authorize Netlify to access your GitHub repositories.

b. Select Repository and Settings:

  • Once connected, select the GitHub repository you want to deploy.
  • Choose the branch you want to deploy (usually main or master).
  • Set the build command to npm run build or the appropriate command for your project.
  • Set the publish directory to the directory containing your build files (typically build or dist).

c. Advanced Build Settings (if required):

  • If additional configuration is needed, you can set environment variables or other build settings in the advanced options.

d. Deploy Site:

  • Click the “Deploy site” button. Netlify will begin building and deploying your site.
  • Once the build process is complete, Netlify will provide you with a unique URL for your deployed site (e.g., https://your-site-name.netlify.app).

e. Test Deployment:

Visit the provided URL to test your deployed site. Ensure that navigation and routing within the application are working as expected without encountering “Page Not Found” errors.

Conclusion

Solving 404 errors on deployments for SPAs is a crucial step in providing a smooth user experience. Netlify’s rewrite/redirect rules is an elixir when using react-router-dom for client-side routing. Using it ensures that your application functions flawlessly in a production environment.

--

--

Signor Dev

Frontend Engineer | Smart Contract Developer | Writer