Last updated: Apr 7, 2024
Reading timeยท5 min
The React Router warning "No routes matched location" is shown for multiple reasons:
<Route />
component with the given path
hasn't been set.Routes
components./users/*
to
match descendent routes.Route
for a specific pathHere is an example of how the warning is raised.
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 />
componentHowever, if I try to navigate to /contacts
in my browser, I get the following
warning:
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.
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>; }
We added a /contacts
Route, so when the user tries to navigate to the
/contacts
page, the <Contacts />
component is rendered.
<Route path="/contacts" element={<Contacts />} />
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.
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>; }
Note that the route that matches all unmatched <Route />
components paths has
to be placed last.
<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.
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.
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>; }
The following <Route />
matches /users/123
, /users/456
, /users/abc
, etc.
<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.
In some cases, you might want to navigate to a different route if a certain path is requested.
Here is an example.
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>; }
When the user requests /about
or /about/123
, then the <About />
component
is rendered.
<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.
In some cases, you might need to use multiple layouts in a React Router application, e.g. anonymous/authenticated.
Here is a short example.
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> ); };
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.
To resolve the React Router warning "No routes matched location", make sure:
<Route />
component with the
given path hasn't been set.<Routes />
components in the same application.You can learn more about the related topics by checking out the following tutorials: