The Route component in React Router (react-router-dom) maps a URL path to the element to render: <Route path="/about" element={<About />} />. Routes live inside <Routes>, which renders the best match for the current URL, and the whole app is wrapped in <BrowserRouter>. This guide covers the React Router DOM Route component from the first route to URL parameters, nested routes with Outlet, index and catch-all (404) routes, redirects, navigation from code and protected routes.
Every example was built with React 19.3.0, react-router-dom 7.18.4 and Vite 8.3.0 (npx vite build) and opened in Microsoft Edge; links were clicked with real mouse events and the outputs are the browser console messages. Reference: Routing in the React Router documentation.
Install React Router
npm install react-router-dom
React Router v7 needs React 18 or later. (In v7 you can also import the same components from react-router; react-router-dom re-exports them.)
Basic Route components
Each Route has a path and an element. Link changes the URL without reloading the page:
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function Home() { return <h2>Home</h2>; }
function About() { return <h2>About us</h2>; }
function Contact() { return <h2>Contact: hello@example.com</h2>; }
export default function App() {
return (
<BrowserRouter>
<nav style={{ display: "flex", gap: 16 }}>
<Link to="/">Home</Link>
<Link to="/about" id="about-link">About</Link>
<Link to="/contact">Contact</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}

/about and only the About route renders.| Route prop | Meaning |
|---|---|
path | URL pattern, e.g. /about, /products/:id, * |
element | What to render when the path matches |
index | Default child of a parent route (no path of its own) |
caseSensitive | Match the path case-sensitively (off by default) |
| children | Nested <Route> elements |
Route parameters with useParams
A segment starting with : is a parameter. Read it in the component with useParams(); the value is always a string:
import { BrowserRouter, Routes, Route, Link, useParams, useLocation } from "react-router-dom";
const products = { 101: "Laptop Stand", 102: "USB-C Hub" };
function Product() {
const { id } = useParams(); // the :id part of the URL
const location = useLocation();
console.log("route matched:", location.pathname, "id =", id);
return <h2>{products[id] ?? "Unknown product"} (id {id})</h2>;
}
export default function App() {
return (
<BrowserRouter>
<Link to="/products/101" id="p101">Laptop Stand</Link> | <Link to="/products/102" id="p102">USB-C Hub</Link>
<Routes>
<Route path="/products/:id" element={<Product />} />
</Routes>
</BrowserRouter>
);
}
Console output (page opened at /products/101, then both links clicked):
route matched: /products/101 id = 101
route matched: /products/101 id = 101
route matched: /products/102 id = 102

/products/:id, renders every product.Nested routes, index routes and Outlet
Put Route elements inside another Route to share a layout. Child paths are relative to the parent, the layout renders the matched child in <Outlet />, and the index route is shown at the parent’s own URL:
import { BrowserRouter, Routes, Route, NavLink, Outlet } from "react-router-dom";
function DashboardLayout() {
const style = ({ isActive }) => ({ fontWeight: isActive ? "bold" : "normal", marginRight: 16 });
return (
<div>
<h2>Dashboard</h2>
<NavLink to="/dashboard" end style={style}>Overview</NavLink>
<NavLink to="/dashboard/orders" style={style} id="orders">Orders</NavLink>
<NavLink to="/dashboard/settings" style={style}>Settings</NavLink>
<div style={{ border: "1px dashed #999", padding: 8, marginTop: 8 }}>
<Outlet /> {/* child routes render here */}
</div>
</div>
);
}
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<p>3 new orders today.</p>} /> {/* /dashboard */}
<Route path="orders" element={<p>Order list: #5001, #5002, #5003</p>} /> {/* /dashboard/orders */}
<Route path="settings" element={<p>Account settings</p>} />
</Route>
<Route path="*" element={<p>404: page not found</p>} />
</Routes>
</BrowserRouter>
);
}

/dashboard/orders the layout stays and the Outlet shows the Orders route; NavLink marks it active.404 page and redirects
path="*" matches any URL no other route matched, which makes it the 404 page. To redirect, render <Navigate to="..." replace /> as the route’s element:
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
function Pricing() {
console.log("Pricing rendered at", window.location.pathname);
return <h2>Pricing</h2>;
}
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<h2>Home</h2>} />
<Route path="/old-pricing" element={<Navigate to="/pricing" replace />} /> {/* redirect */}
<Route path="/pricing" element={<Pricing />} />
<Route path="*" element={<h2>404: nothing at {window.location.pathname}</h2>} /> {/* catch-all */}
</Routes>
</BrowserRouter>
);
}

/blog/missing-post falls through to the * route.Opening /old-pricing in the same app redirects: the console shows Pricing rendered at /pricing. On a real server, make every path return index.html (a “history API fallback”), or refreshing a nested URL returns the server’s own 404.
Navigate from code with useNavigate
After a form submit or login, call navigate(path). navigate(-1) goes back one page:
import { BrowserRouter, Routes, Route, useNavigate } from "react-router-dom";
import { useState } from "react";
function Login() {
const navigate = useNavigate();
const [name, setName] = useState("");
return (
<form onSubmit={(e) => { e.preventDefault(); navigate(`/welcome/${name}`); }}>
<input id="name" placeholder="Your name" value={name} onChange={(e) => setName(e.target.value)} />
<button id="go">Log in</button>
</form>
);
}
function Welcome() {
const navigate = useNavigate();
console.log("now at", window.location.pathname);
return <p>Welcome! <button onClick={() => navigate(-1)}>Back</button></p>;
}
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/welcome/:name" element={<Welcome />} />
</Routes>
</BrowserRouter>
);
}
Console output after typing Priya and clicking “Log in”:
now at /welcome/Priya
Protected routes
Wrap the element of a private route in a small component that checks the user and redirects guests:
import { BrowserRouter, Routes, Route, Navigate, Link } from "react-router-dom";
const user = null; // not logged in
function RequireAuth({ children }) {
if (!user) return <Navigate to="/login" replace />; // send guests to the login page
return children;
}
export default function App() {
return (
<BrowserRouter>
<Link to="/account" id="account">My account</Link>
<Routes>
<Route path="/" element={<h2>Home</h2>} />
<Route path="/login" element={<h2>Please log in</h2>} />
<Route path="/account" element={<RequireAuth><h2>Account details</h2></RequireAuth>} />
</Routes>
</BrowserRouter>
);
}

/login.Route in React Router v5 vs v6/v7
| v5 | v6 and v7 |
|---|---|
<Switch> | <Routes> |
component={About} or render | element={<About />} |
exact | Not needed: routes match exactly by default |
<Redirect> | <Navigate> |
useHistory() | useNavigate() |
match.params | useParams() |
Related React tutorials on this site:
- Pass props to a component in React
- Use React components with children
- Open a React component in a new tab
- Set up a React environment
Frequently asked questions
What is the Route component in React Router?
It maps a URL path to an element: <Route path="/about" element={<About />} />. Routes are placed inside <Routes>.
How do I get URL parameters in a route?
Define the parameter with a colon (path="/users/:id") and read it with const { id } = useParams().
How do I make a 404 route?
Add <Route path="*" element={<NotFound />} /> as the last route.
How do I redirect in React Router v6 and v7?
Render <Navigate to="/new-path" replace />, or call navigate("/new-path") from useNavigate().
What replaced Switch and the component prop?
Routes replaced Switch, and the element prop replaced component and render.
How do nested routes work?
Put child Routes inside a parent route and render <Outlet /> in the parent’s element; child paths are relative.
