No routes matched location in React Router [Solved]

avatar
Borislav Hadzhiev

Last updated: May 12, 2023
5 min

banner

# No routes matched location in React Router [Solved]

The React Router warning "No routes matched location" is shown for multiple reasons:

  • trying to access a route for which a <Route /> component with the given path hasn't been set.
  • using multiple Routes components.
  • forgetting to specify a wildcard matcher for a subpath, e.g. /users/* to match descendent routes.
  • using multiple layouts incorrectly (e.g. anonymous/authenticated).

no routes matched location

# Forgetting to set up a Route for a specific path

Here is an example of how the warning is raised.

App.js
import React from 'react'; import { BrowserRouter as Router, Route, Link, Routes, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> </ul> </nav> <Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; }

The App component above has Route components for the paths:

  • /about > renders the <About /> component
  • / > renders the <Home /> component

However, if I try to navigate to /contacts in my browser, I get the following warning:

  • No routes matched location "/contacts"

no routes matched location

This is caused because there is no Route component that matches the /contacts path.

One way to get around this is to set up a <Route /> that matches the specified in the warning message path.

App.js
import React from 'react'; import { BrowserRouter as Router, Route, Link, Routes, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/contacts">Contacts</Link> </li> </ul> </nav> <Routes> <Route path="/about" element={<About />} /> <Route path="/contacts" element={<Contacts />} /> <Route path="/" element={<Home />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function Contacts() { return <h2>Contacts</h2>; }

create route that matches specified path

We added a /contacts Route, so when the user tries to navigate to the /contacts page, the <Contacts /> component is rendered.

App.js
<Route path="/contacts" element={<Contacts />} />

# Creating a Route that matches all unmatched paths

However, in some cases, you might want to create a <Route /> that matches all unmatched paths.

In this case, you can use a wildcard match * character.

App.js
import React from 'react'; import { BrowserRouter as Router, Route, Link, Routes, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/contacts">Contacts</Link> </li> </ul> </nav> <Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> {/* ๐Ÿ‘‡๏ธ MUST BE SPECIFIED LAST IN THE LIST OF ROUTE components ๐Ÿ‘‡๏ธ */} <Route path="*" element={<MatchAllRoute />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function MatchAllRoute() { return <h2>The requested page does not exist</h2>; }

create match all paths route

Note that the route that matches all unmatched be previous <Route /> components paths has to be placed last.

App.js
<Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> {/* ๐Ÿ‘‡๏ธ MUST BE SPECIFIED LAST IN THE LIST OF ROUTE components ๐Ÿ‘‡๏ธ */} <Route path="*" element={<MatchAllRoute />} /> </Routes>

Now when the user tries to access any path that is not /about or /, the <MatchAllRoute /> component is rendered.

# Creating a Route that matches all subpaths of a path

The "No routes matched location" warning is also shown when you haven't created a <Route /> that matches all subpaths of a path.

For example, suppose that you have a /users route but need to create a route that matches /users/1, /users/2, or /users/N.

In this case, you have to use a wildcard matcher for the subpath.

App.js
import React from 'react'; import { BrowserRouter as Router, Route, Link, Routes, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/users">Users</Link> </li> <li> <Link to="/users/123">User 123</Link> </li> <li> <Link to="/users/456">Users 456</Link> </li> </ul> </nav> <Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> <Route path="/users" element={<Users />} /> {/* Use a route that matches all /users/ subpaths */} <Route path="/users/*" element={<UserDetails />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function Users() { return <h2>Users</h2>; } function UserDetails() { return <h2>User Details</h2>; }

create route that matches all specified subpaths

The following <Route /> matches /users/123, /users/456, /users/abc, etc.

App.js
<Route path="/users/*" element={<UserDetails />} />

Any subpath of /users is matched by the <Route /> and the <UserDetails /> component is rendered.

This is useful when you need to dynamically render a link to a detailed page and don't necessarily know the complete path ahead of time.

# Navigating to a different route when a certain path is requested

In some cases, you might want to navigate to a different route if a certain path is requested.

Here is an example.

App.jsx
import React from 'react'; import { BrowserRouter as Router, Route, Link, Routes, Navigate, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/users">Users</Link> </li> </ul> </nav> <Routes> <Route path="/about/*" element={<About />} /> <Route path="/users/*" element={<Users />} /> <Route path="/" element={<Navigate to="/about" />} /> </Routes> </div> </Router> ); } function About() { return <h2>About</h2>; } function Users() { return <h2>Users</h2>; }

navigate to different route when path requested

When the user requests /about or /about/123, then the <About /> component is rendered.

App.js
<Routes> <Route path="/about/*" element={<About />} /> <Route path="/users/*" element={<Users />} /> <Route path="/" element={<Navigate to="/about" />} /> </Routes>

Similarly, when they request /users or /users/123, then the <Users /> component is rendered.

We also want to render the <About /> component when the user goes to /, so we used the <Navigate /> component to render the /about route when the user goes to /.

You don't necessarily have to match the subpaths with an asterisk if your use case doesn't require it.

# Using multiple layouts in React Router

In some cases, you might need to use multiple layouts in a React Router application, e.g. anonymous/authenticated.

Here is a short example.

App.js
import React from 'react'; import { BrowserRouter as Router, Route, Link, Routes, Outlet, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/login">Login</Link> </li> </ul> </nav> <AppRoute /> </div> </Router> ); } function Login() { return <h2>Login Page</h2>; } function AnonymousLayout() { return ( <div> <h1>Anonymous Users Page</h1> <Outlet /> </div> ); } const AppRoute = () => { return ( <Routes> <Route path="/" element={<AnonymousLayout />}> <Route path="login" element={<Login />} /> {/* rendered when no nested routes match */} <Route index element={<h2>Default Page</h2>} /> </Route> </Routes> ); };

using multiple layouts in react router

The Outlet component is used in a parent route to render their child route elements.

The AnonymousLayout component is always rendered and when the user goes to the /login page, the <Login /> component is rendered.

The AnonymousLayout component has to render an Outlet component so that its child route elements get rendered.

# Conclusion

To resolve the React Router warning "No routes matched location", make sure:

  • You aren't trying to access a route for which a <Route /> component with the given path hasn't been set.
  • You haven't forgotten to specify a wildcard matcher for a subpath.
  • You haven't used multiple layouts incorrectly (e.g. anonymous/authenticated).
  • You don't have multiple <Routes /> components in the same application.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2023 Borislav Hadzhiev