New webinar: "The Remote Job Search: My Microverse Journey" with graduate Paul Rail
Watch Now


With approximately 3.6 million downloads on npm, React Router is one of the most popular libraries for React. Used for building interfaces, it is a fully-featured client and server-side routing library.

In a Single-Page Application (SPA), instead of reloading entire pages from a server, only some sections are rewritten. This powerful library allows you to navigate among the views of various components in a React application. It changes the browser URL while keeping the UI on track with it.

In September 2021, with the release of React-Router V6 came several improvements and significant syntax changes. One significant change is the bundle size which is 60% smaller than those in React-Router V5, resulting in much quicker load times.

In this guide I’m going to talk about the most important changes, giving a step-by-step guide on how to migrate your project to the newest version.

Setting Up React-Router

Installing React-Router is very straightforward. After creating your react app, inside your root folder, run: 
{% code-block language="js" %}
npm install react-router-dom@6
{% code-block-end %} 

If you are completely new to React, you can check React’s documentation for more details on how to set up your app.

You can also check out the Introduction to ReactJS published on our blog to understand React basics. 

Adding Routes to your Application

The different pages in your application are different components that will render whatever you decide to code. There are no rules for the location of files. To keep things organized, in this example, I’ll keep the following structure:

React-Router Library

Routes Configuration: Differences Between React-Router V5 and React-Router V6

Now that we have all our files, we need to set up our routes. In React-Router V5, the routing configuration was done by having a <Switch> which wrapped <Route>s with their respective child components, like the following:

{% code-block language="js" %} 
<Redirect exact from="/" to="/home" />
<Route path="/about">
<About />
<Route path="/users">
<Users />
<Route path="/home">
<Home />
</Switch> {% code-block-end %}

In React-Router V6, we no longer have a <Switch> component. We set up routes with a <Routes> wrapper, with <Route>s components passing their path prop and respective components as an element, as follows:

{% code-block language="js" %} 
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="users" element={<Users />} />
</Routes> {% code-block-end %}

It is also important to mention that the new React-Router V6 does not accept anything but a <Route> inside the <Routes> wrapper. In the case of switching React-Router V5 to V6  for instance, if you simply swapped the <Switch> wrapper with <Routes>, it would compile, but wouldn’t display anything.

What Happens if You Try to Use <Switch> in React-Router V6?

With the release of React-Router V6, the usage of <Switch> will result in the following error:

{% code-block language="js" %} Attempted import error: 'Switch' is not exported from 'react-router-dom' (imported as 'Switch').
ERROR in ./src/index.js 13:33-39
export 'Switch' (imported as 'Switch') was not found in 'react-router-dom' (possible exports: BrowserRouter, HashRouter, Link, MemoryRouter, NavLink, Navigate, NavigationType, Outlet, Route, Router, Routes, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, createPath, createRoutesFromChildren, createSearchParams, generatePath, matchPath, matchRoutes, parsePath, renderMatches, resolvePath, unstable_HistoryRouter, useHref, useInRouterContext, useLinkClickHandler, useLocation, useMatch, useNavigate, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useSearchParams) {% code-block-end %}

It is also significant to mention that the same applies to the <Redirect> component. So if you ever find yourself with this compiling error, double-check whether the component exists or not in the version you are currently using.

How to Set Up a 404 page

The 404 page is a no-match page that will be used when the user tries to navigate to a non-existing path. First things first, you need to create a component that will display your message error, or image, like so:

Error screen

Setting up a no match page is pretty straightforward in both React-Router V5 and React-Router V6. In older versions of React-Router, just like the other Switch/Route routes, your <NoMatch> component will be wrapped inside a <Route>, without a path prop:

{% code-block language="js" %}
<NoMatch />
</Route> {% code-block-end %}

For the latest version, it is also necessary to have a <NoMatch /> component, but we use the new element prop, as well as the following path:

{% code-block language="js" %}
<Route path="*" element={<NoMatch />} />
{% code-block-end %}

Navigating through Routes

Now that we have all our routes and paths, it’s time to set a way to navigate through them. The most common way is to have a header with links to their respective routes/paths.

The syntax is the same for both React-Router V5 and React-Router V6, you just need <Link>s with “to” props pointing to their respective routes. To keep the HTML semantic, it is a good practice to keep them wrapped in a <Nav> tag:

{% code-block language="js" %}
<Link to="/">Home</Link> |{" "}
<Link to="/about">About</Link> |{" "}
<Link to="/users">Users</Link>
{% code-block-end %}

Is it Possible to Add Styles to Links?

Yes! It is also possible to style the navigation links when the current one is accessed or “active”. This can be done with a special kind of <Link> called a <NavLink>.

To do so, you can pass a function to a style or className, if you are using a front-end framework, for instance, that will allow inline styling to the link based on its active state. One of the easiest ways to do this is by creating a variable to store your inline styling and using a ternary operator:

{% code-block language="js" %} import * as React from "react";
import { NavLink } from "react-router-dom";
function NavList() {
let activeStyle = {
fontWeight: ‘bold’,
color: ‘green’
let activeClassName = "fw-bold text-success";
return (
style={ ({ isActive }) => isActive? activeStyle: undefined }
</NavLink> |{" "}
className={ ({ isActive }) => isActive ? activeClassName : undefined }
</NavLink> |{" "}
<NavLink to="/users">
{({ isActive }) => (
<span className={ isActive ? activeClassName : undefined }>
)}; {% code-block-end %}

Want to learn more about React?

If you want to learn more about React and software development, learn how to get set up with React/Redux in your next multi-page project.

Subscribe to our Newsletter

Get Our Insights in Your Inbox

Career advice, the latest coding trends and languages, and insights on how to land a remote job in tech, straight to your inbox.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
We use own and third party cookies to; provide essential functionality, analyze website usages, personalize content, improve website security, support third-party integrations and/or for marketing and advertising purposes.

By using our website, you consent to the use of these cookies as described above. You can get more information, or learn how to change the settings, in our Cookies Policy. However, please note that disabling certain cookies may impact the functionality and user experience of our website.

You can accept all cookies by clicking the "Accept" button or configure them or refuse their use by clicking HERE.