---
title: Upgrading from v5
order: 1
---
# Upgrading from v5
## Backwards Compatibility Package
We are actively working on a backwards compatibility layer that implements the v5 API on top of the v6 implementation. This will make upgrading as smooth as possible. You'll be able to upgrade to v6 with minimal changes to your application code. Then, you can incrementally update your code to the v6 API.
We recommend waiting for the backwards compatibility package to be released before upgrading apps that have more than a few routes.
Until then, we hope this guide will help you do the upgrade all at once!
## Introduction
React Router version 6 introduces several powerful new features, as well as improved compatibility with the latest versions of React. It also introduces a few breaking changes from version 5. This document is a comprehensive guide on how to upgrade your v4/5 app to v6 while hopefully being able to ship as often as possible as you go.
If you are just getting started with React Router, or you'd like to try out v6 in a new app, please see [the Getting Started guide](../getting-started/installation.md).
The examples in this guide will show code samples of how you might have built something in a v5 app, followed by how you would accomplish the same thing in v6. There will also be an explanation of why we made this change and how it's going to improve both your code and the overall user experience of people who are using your app.
In general, the process looks like this:
1. [Upgrade to React v16.8 or greater](#upgrade-to-react-v168)
2. [Upgrade to React Router v5.1](#upgrade-to-react-router-v51)
- [Remove ``s inside ``](#remove-redirects-inside-switch)
- [Refactor custom ``s](#refactor-custom-routes)
3. [Upgrade to React Router v6](#upgrade-to-react-router-v6)
The following is a detailed breakdown of each step that should help you migrate quickly and with confidence to v6.
## Upgrade to React v16.8
React Router v6 makes heavy use of [React hooks](https://reactjs.org/docs/hooks-intro.html), so you'll need to be on React 16.8 or greater before attempting the upgrade to React Router v6. The good news is that React Router v5 is compatible with React >= 15, so if you're on v5 (or v4) you should be able to upgrade React without touching any of your router code.
Once you've upgraded to React 16.8, **you should deploy your app**. Then you can come back later and pick up where you left off.
## Upgrade to React Router v5.1
It will be easier to make the switch to React Router v6 if you upgrade to v5.1 first. In v5.1, we released an enhancement to the handling of `` elements that will help smooth the transition to v6. Instead of using `` and `` props, just use regular element `` everywhere and use hooks to access the router's internal state.
```js
// v4 and v5 before 5.1
function User({ id }) {
// ...
}
function App() {
return (
(
)}
/>
);
}
// v5.1 preferred style
function User() {
let { id } = useParams();
// ...
}
function App() {
return (
{/* Can also use a named `children` prop */}
} />
);
}
```
You can read more about v5.1's hooks API and the rationale behind the move to regular elements [on our blog](https://reacttraining.com/blog/react-router-v5-1/).
In general, React Router v5.1 (and v6) favors elements over components (or "element types"). There are a few reasons for this, but we'll discuss more further down when we discuss v6's `` API.
When you use regular React elements you get to pass the props explicitly. This helps with code readability and maintenance over time. If you were using `` to get a hold of the params, you can just
`useParams` inside your route component instead.
Along with the upgrade to v5.1, you should replace any usage of `withRouter` with hooks. You should also get rid of any "floating" `` elements that are not inside a ``. Again, [the blog post about v5.1](https://reacttraining.com/blog/react-router-v5-1/) explains how to do this in greater detail.
In summary, to upgrade from v4/5 to v5.1, you should:
- Use `` instead of `` and/or ``
props
- Use [our hooks API](https://reacttraining.com/react-router/web/api/Hooks) to
access router state like the current location and params
- Replace all uses of `withRouter` with hooks
- Replace any ``s that are not inside a `` with `useRouteMatch`,
or wrap them in a ``
### Remove ``s inside ``
Remove any `` elements that are directly inside a ``.
If you want to redirect on the initial render, you should move the redirect logic to your server (we [wrote more about this here](https://gist.github.com/mjackson/b5748add2795ce7448a366ae8f8ae3bb)).
If you want to redirect client-side, move your `` into a `` prop.
```tsx
// Change this:
// to this:
} />
```
Normal `` elements that are not inside a `` are ok to remain. They will become `` elements in v6.
### Refactor custom ``s
Replace any elements inside a `` that are not plain `` elements with a regular ``. This includes any ``-style custom components.
You can [read more about the rationale behind this here](https://gist.github.com/mjackson/d54b40a094277b7afdd6b81f51a0393f), including some tips about how to use a `` prop in v5 to achieve the same effect.
### Ship it!
Again, **once your app is upgraded to v5.1 you should test and deploy it**, and pick this guide back up when you're ready to continue.
## Upgrade to React Router v6
**Heads up:** This is the biggest step in the migration and will probably take the most time and effort.
For this step, you'll need to install React Router v6. If you're managing dependencies via npm:
```bash
$ npm install react-router-dom
# or, for a React Native app
$ npm install react-router-native
```
You'll also want to remove the `history` dependency from your package.json. The `history` library is a direct dependency of v6 (not a peer dep), so you won't ever import or use it directly. Instead, you'll use the `useNavigate()` hook for all navigation (see below).
### Upgrade all `` elements to ``
React Router v6 introduces a `Routes` component that is kind of like `Switch`, but a lot more powerful. The main advantages of `Routes` over `Switch` are:
- All ``s and ``s inside a `` are relative. This leads to
leaner and more predictable code in `` and ``
- Routes are chosen based on the best match instead of being traversed in order.
This avoids bugs due to unreachable routes because they were defined later
in your ``
- Routes may be nested in one place instead of being spread out in different
components. In small to medium-sized apps, this lets you easily see all your
routes at once. In large apps, you can still nest routes in bundles that you
load dynamically via `React.lazy`
In order to use v6, you'll need to convert all your `` elements to ``. If you already made the upgrade to v5.1, you're halfway there.
First, let's talk about relative routes and links in v6.
### Relative Routes and Links
In v5, you had to be very explicit about how you wanted to nest your routes and links. In both cases, if you wanted nested routes and links you had to build the `` and `` props from the parent route's `match.url` and `match.path` properties. Additionally, if you wanted to nest routes, you had to put them in the child route's component.
```js
// This is a React Router v5 app
import {
BrowserRouter,
Switch,
Route,
Link,
useRouteMatch,
} from "react-router-dom";
function App() {
return (
);
}
function Users() {
// In v5, nested routes are rendered by the child component, so
// you have elements all over your app for nested UI.
// You build nested routes and links using match.url and match.path.
let match = useRouteMatch();
return (
);
}
```
This is the same app in v6:
```js
// This is a React Router v6 app
import {
BrowserRouter,
Routes,
Route,
Link,
} from "react-router-dom";
function App() {
return (
} />
} />
);
}
function Users() {
return (
} />
} />
);
}
```
A few important things to notice about v6 in this example:
- `` and `` are relative. This means that they
automatically build on the parent route's path and URL so you don't have to
manually interpolate `match.url` or `match.path`
- `` is gone. Instead, routes with descendant routes (defined in
other components) use a trailing `*` in their path to indicate they match
deeply
- You may put your routes in whatever order you wish and the router will
automatically detect the best route for the current URL. This prevents bugs
due to manually putting routes in the wrong order in a ``
You may have also noticed that all `` from the v5 app changed to `` in v6. Assuming you followed the upgrade steps to v5.1, this should be as simple as moving your route element from the child position to a named `element` prop.
### Advantages of ``
In the section about upgrading to v5.1, we promised that we'd discuss the advantages of using regular elements instead of components (or element types) for rendering. Let's take a quick break from upgrading and talk about that now.
For starters, we see React itself taking the lead here with the `}>` API. The `fallback` prop takes a React element, not a component. This lets you easily pass whatever props you want to your `` from the component that renders it.
Using elements instead of components means we don't have to provide a `passProps`-style API so you can get the props you need to your elements. For example, in a component-based API there is no good way to pass props to the `` element that is rendered when `` matches. Most React libraries who take this approach end up with either an API like `` or use a render prop or higher-order component.
Also, in case you didn't notice, in v4 and v5 `Route`'s rendering API became rather large. It went something like this:
```js
// Ah, this is nice and simple!
// But wait, how do I pass custom props to the element??
// Hmm, maybe we can use a render prop in those situations?
(
)}
/>
// Ok, now we have two ways to render something with a route. :/
// But wait, what if we want to render something when a route
// *doesn't* match the URL, like a Not Found page? Maybe we
// can use another render prop with slightly different semantics?
(
match ? (
) : (
)
)}
/>
// What if I want to get access to the route match, or I need
// to redirect deeper in the tree?
function DeepComponent(routeStuff) {
// got routeStuff, phew!
}
export default withRouter(DeepComponent);
// Well hey, now at least we've covered all our use cases!
// ... *facepalm*
```
At least part of the reason for this API sprawl was that React did not provide any way for us to get the information from the `` to your route element, so we had to invent clever ways to get both the route data **and** your own custom props through to your elements: `component`, render props, `passProps` higher-order-components ... until **hooks** came along!
Now, the conversation above goes like this:
```js
// Ah, nice and simple API. And it's just like the API!
// Nothing more to learn here.
} />
// But wait, how do I pass custom props to the
// element? Oh ya, it's just an element. Easy.
} />
// Ok, but how do I access the router's data, like the URL params
// or the current location?
function Profile({ animate }) {
let params = useParams();
let location = useLocation();
}
// But what about components deep in the tree?
function DeepComponent() {
// oh right, same as anywhere else
let navigate = useNavigate();
}
// Aaaaaaaaand we're done here.
```
Another important reason for using the `element` prop in v6 is that `` is reserved for nesting routes. This is one of people's favorite features from v3 and `@reach/router`, and we're bringing it back in v6. Taking the code in the previous example one step further, we can hoist all `` elements into a single route config:
```js
// This is a React Router v6 app
import {
BrowserRouter,
Routes,
Route,
Link,
Outlet,
} from "react-router-dom";
function App() {
return (
} />
}>
} />
} />
);
}
function Users() {
return (
);
}
```
This step is optional of course, but it's really nice for small to medium sized apps that don't have thousands of routes.
Notice how `` elements nest naturally inside a `` element. Nested routes build their path by adding to the parent route's path. We didn't need a trailing `*` on `` this time because when the routes are defined in one spot the router is able to see all your nested routes.
You'll only need the trailing `*` when there is another `` somewhere in that route's descendant tree. In that case, the descendant `` will match on the portion of the pathname that remains (see the previous example for what this looks like in practice).
When using a nested config, routes with `children` should render an `` in order to render their child routes. This makes it easy to render layouts with nested UI.
### Note on `` patterns
React Router v6 uses a simplified path format. `` in v6 supports only 2 kinds of placeholders: dynamic `:id`-style params and `*` wildcards. A `*` wildcard may be used only at the end of a path, not in the middle.
All of the following are valid route paths in v6:
```
/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
```
The following RegExp-style route paths are **not valid** in v6:
```
/users/:id?
/tweets/:id(\d+)
/files/*/cat.jpg
/files-*
```
We added the dependency on path-to-regexp in v4 to enable more advanced pattern matching. In v6 we are using a simpler syntax that allows us to predictably parse the path for ranking purposes. It also means we can stop depending on path-to-regexp, which is nice for bundle size.
If you were using any of path-to-regexp's more advanced syntax, you'll have to remove it and simplify your route paths. If you were using the RegExp syntax to do URL param validation (e.g. to ensure an id is all numeric characters) please know that we plan to add some more advanced param validation in v6 at some point. For now, you'll need to move that logic to the component the route renders, and let it branch it's rendered tree after you parse the params.
If you were using `` you should move it to its containing `` prop. Either all routes in a `` element are case-sensitive or they are not.
One other thing to notice is that all path matching in v6 ignores the trailing slash on the URL. In fact, `` has been removed and has no effect in v6. **This does not mean that you can't use trailing slashes if you need to.** Your app can decide to use trailing slashes or not, you just can't render two different UIs _client-side_ at `` and ``. You can still render two different UIs at those URLs (though we wouldn't recommend it), but you'll have to do it server-side.
### Note on `` values
In v5, a `` value that does not begin with `/` was ambiguous; it depends on what the current URL is. For example, if the current URL is `/users`, a v5 `` would render a ``. However, if the current URL has a trailing slash, like `/users/`, the same `` would render ``. This makes it difficult to predict how links will behave, so in v5 we recommended that you build links from the root URL (using `match.url`) and not use relative `` values.
React Router v6 fixes this ambiguity. In v6, a `` will always render the same ``, regardless of the current URL.
For example, a `` that is rendered inside a `` will always render a link to `/users/me`, regardless of whether or not the current URL has a trailing slash.
When you'd like to link back "up" to parent routes, use a leading `..` segment in your `` value, similar to what you'd do in a ``.
```tsx
function App() {
return (
}>
} />
);
}
function Users() {
return (
{/* This links to /users - the current route */}
Users
{users.map((user) => (
{/* This links to /users/:id - the child route */}
{user.name}
))}
);
}
function UserProfile() {
return (
{/* This links to /users - the parent route */}
All Users
{/* This links to /users/:id - the current route */}
User Profile
{/* This links to /users/mj - a "sibling" route */}
MJ