React Router is a client-side routing library for React. It maps URL paths to components so moving between pages changes the view without a full browser reload. This tutorial covers the three pieces every React Router app starts with: routes, links, and layouts.
The examples use React Router 8 and its declarative BrowserRouter mode. This is the simplest way to add routing to a standard React project, and every API shown here imports from one package. You can keep the same package as the app grows, since React Router also ships a data mode and a framework mode for server rendering.
Install and mount the router
React Router ships as a single npm package called react-router. Install it, then wrap your app in a BrowserRouter so the router can read the current URL and re-render on navigation.
npm install react-routerOlder tutorials import from react-router-dom. React Router 7 merged that package into react-router, so current code imports everything from react-router.
BrowserRouter watches the browser History API and keeps the URL bar in sync with the UI. Mount it once around your root component in main.jsx. The router holds the current location in context, so any component below it can read the URL.
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router";
import App from "./App.jsx";
createRoot(document.getElementById("root")).render(
<BrowserRouter>
<App />
</BrowserRouter>
);Everything inside BrowserRouter can now read the URL and render route matches. A full walkthrough, including the create command, is in how to add React Router to a Vite project.
Map paths to components with Routes
Routes is where URLs meet components. The Routes component holds Route children, and each Route maps one path to one element.
import { Routes, Route } from "react-router";
import Home from "./pages/Home.jsx";
import About from "./pages/About.jsx";
export default function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
);
}When the URL is /, React Router renders Home. When it is /about, it renders About. Visiting any other path renders nothing, because no route matches.
React Router ranks route paths, so a more specific path wins even when it is listed later. Each element is a normal React component, so pages can hold any state and markup you already write.
That empty result for unknown paths is why most apps add a catch-all route later. The 404 pattern is covered in how to build a 404 page with React Router.
Navigate with Link
Links between pages use the Link component instead of raw anchor tags. Link renders an anchor element but intercepts the click so React Router can swap components without reloading the page.
import { Link } from "react-router";
export default function Nav() {
return (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
);
}Clicking About updates the URL to /about and renders the About route, with no network request for a new HTML document. Link also lets users open a page in a new tab or copy the address, because it renders a real anchor element with an href.
NavLink works the same way but adds an active class to the link that matches the current URL.
import { NavLink } from "react-router";
export default function Nav() {
return (
<nav>
<NavLink to="/" end>Home</NavLink>
<NavLink to="/about">About</NavLink>
</nav>
);
}The end prop on the first link stops it from matching every path. Without it, the / link would also look active on /about. Use NavLink where an active state helps, like a navigation bar or a set of tabs.
Share a layout with nested routes
A layout is a page frame shared by several routes, like a header and a content area. Instead of repeating the header in every page, nest the routes under one parent and render the active child with Outlet.
The Layout component is the frame. It renders the shared header once and leaves an Outlet where the active page should appear.
import { Outlet } from "react-router";
function Layout() {
return (
<div>
<header>My site</header>
<Outlet />
</div>
);
}The App component then nests the two pages under this layout route. The parent Route has no path, so it adds the frame without changing the URL.
import { Routes, Route } from "react-router";
import Home from "./pages/Home.jsx";
import About from "./pages/About.jsx";
export default function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
);
}When /about matches, React Router renders About into the Outlet inside Layout, so the header stays put while the content changes.
A parent without a path is only one nesting option. Parent routes can also own a URL prefix and render deeper children, which how to create nested routes with React Router explains in depth.
When React Router helps
A single page app can fake navigation with state, but the URL never changes. React Router keeps the address bar honest, so refresh, bookmarks, share links, and the back button all work the way users expect.
What to learn next
This declarative setup is the smallest complete React Router app. From here, add URL parameters for product and post pages, or explore how the declarative, data, and framework modes differ when an app grows beyond client-side rendering. Buttons that navigate after an action use the useNavigate hook.
Common early mistakes are importing from the old react-router-dom package, forgetting to wrap the app in BrowserRouter, and nesting routes without an Outlet in the parent.
Rune AI
Key Insights
- Install the react-router package and wrap the app in BrowserRouter.
- Declare one Route per URL path inside Routes.
- Use Link for navigation and NavLink for active styling.
- Nest routes and render the child with Outlet.
Frequently Asked Questions
Do I need a server to use React Router?
What package do I install?
Is React Router a framework or a library?
Conclusion
React Router maps URL paths to components in a client-side React app. Configure routes with Routes and Route, navigate with Link, and share a page frame with nested routes and Outlet. Add a Vite setup and deeper routing guides when you are ready to build further.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.