Defining Routes
In this page:
The Routes and Route Relationship
<Routes> acts as a switchboard: it looks at the current URL and renders only the single <Route> inside it whose path matches. Each <Route> pairs a URL path with the component (via the element prop) that should be shown for that path.
Note: Order matters less in v6 than v5 since v6 picks the best match automatically, but keeping specific paths before general ones is still good practice.
Warning: In React Router v6, every <Route> needs the element prop — the older component prop from v5 no longer works.
Example: The Routes and Route Relationship
// Run in your local React project (npm install required)
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function Home() { return <p>Home</p>; }
function Contact() { return <p>Contact</p>; }
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
Catching Unmatched Routes with a Wildcard
A <Route path='*'> matches any URL that didn't match an earlier, more specific route. Placing it last inside <Routes> makes it act as a catch-all 404 page for any address your app doesn't explicitly handle.
Note: Give the 404 route a helpful message and a link back to home, rather than a bare 'not found' text.
Warning: If the wildcard route is placed FIRST instead of last, it can match everything and prevent your other, more specific routes from ever being reached.
Example: Catching Unmatched Routes with a Wildcard
// Run in your local React project (npm install required)
import { Routes, Route } from 'react-router-dom';
function Home() { return <p>Home</p>; }
function NotFound() { return <p>404 - Not found</p>; }
function AppRoutes() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
}
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
Rendering Multiple Routes for the Same Layout
Several distinct paths can render different top-level pages while still sharing the same overall app shell (like a fixed navigation bar) if that shell is placed outside the <Routes> block. Only the part matched by a specific Route swaps out as the URL changes.
Note: Keep persistent UI (navbar, footer) outside <Routes>, and only put page-specific content inside individual routes' elements.
Warning: Duplicating the navbar JSX inside every route's element component means it re-mounts (and loses any local state) on every navigation.
Example: Rendering Multiple Routes for the Same Layout
// Run in your local React project (npm install required)
import { Routes, Route } from 'react-router-dom';
function Nav() { return <nav>My Site</nav>; }
function Home() { return <p>Home</p>; }
function About() { return <p>About</p>; }
function App() {
return (
<div>
<Nav />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
);
}
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
- Forgetting the element prop on <Route>, which was required starting in React Router v6 (v5 used component instead).
- Ordering routes so a more general path accidentally matches before a more specific one.
- Not wrapping <Route> elements inside a <Routes> parent — a common leftover from React Router v5 code.
- <Routes> is a container that renders the first <Route> whose path matches the current URL.
- Each <Route> maps a path string to the element that should render for it.
- React Router v6 uses the element prop (element={<Home />}) instead of v5's component prop.
- A path of '*' is commonly used as a catch-all for unmatched routes (404 pages).
Requires npm install react-router-dom (v6 syntax shown) — not available via CDN in this sandbox.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: