Introduction to React Router: Building Multi-Page SPAs
Learn how to use React Router to transform your dashboard into a seamless single-page application (SPA) with efficient routing and navigation.
Previously in this course, we built a robust global state management system using Introduction to Context API: Avoiding Prop Drilling in React and Introduction to Custom Hooks: Master Abstraction in React. While our dashboard handles data well, it currently lives on a single page. Today, we’ll move beyond that limitation by implementing react router, the industry-standard library for handling navigation in a Single Page Application (SPA).
The Concept: Why Routing Matters in an SPA
In a traditional multi-page website, clicking a link triggers a browser request to the server, which then sends back an entirely new HTML document. This is slow and causes a jarring "flicker" as the page reloads.
In an SPA, the server sends one initial HTML file. When a user clicks a link, the JavaScript (React) intercepts the event, updates the URL, and swaps out the components currently visible on the screen. This makes your dashboard feel snappy and app-like. React Router acts as the "traffic controller," mapping URL paths to specific component trees.
Step 1: Installing and Configuring React Router
First, install the library in your project:
Bashnpm install react-router-dom
To set up routing, we need to wrap our application in a provider. This provider uses the History API under the hood to track where the user is and where they are going.
In your main.jsx (or index.js), wrap your App component with BrowserRouter:
JSXimport { BrowserRouter } from CE9178">'react-router-dom'; root.render( <BrowserRouter> <App /> </BrowserRouter> );
Step 2: Defining Routes
Now that the router is listening, we define which components should render at which paths. We use the Routes component as a container and individual Route components to define the mapping.
JSXimport { Routes, Route } from CE9178">'react-router-dom'; import Dashboard from CE9178">'./Dashboard'; import Settings from CE9178">'./Settings'; function App() { return ( <Routes> <Route path="/" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> </Routes> ); }
When the URL ends in /, the Dashboard component renders. When it ends in /settings, the Settings component replaces it.
Step 3: Navigating Between Pages
Never use standard <a> tags for internal navigation in an SPA. An <a> tag will force a full browser reload, destroying your React state. Instead, use the Link component provided by React Router.
JSXimport { Link } from CE9178">'react-router-dom'; function Navigation() { return ( <nav> <Link to="/">Dashboard</Link> <Link to="/settings">Settings</Link> </nav> ); }
The Link component renders an <a> tag in the DOM, but it prevents the default browser behavior and tells the router to update the view without a refresh.
Hands-on Exercise
- Add a new page component called
Profile.jsxto your project. - Add a new
Routeto yourApp.jsmapping the path/profileto yourProfilecomponent. - Update your navigation menu to include a link to the profile page.
- Verify that you can click between the Dashboard, Settings, and Profile without the page reloading.
Common Pitfalls
- Forgetting the BrowserRouter: If you try to use
LinkorRoutesoutside of aBrowserRoutercomponent, your application will throw an error. Ensure the provider is at the very top of your component tree. - The "Double Slash" Bug: Be careful with paths. While React Router is forgiving, standardizing your paths (e.g., always using
/settingsinstead ofsettings/) prevents broken links as your app grows. - Using
window.location: Avoid using the browser's native location API to change routes. React Router needs to manage the state internally; bypassing it will break the "back" button functionality.
Recap
We've successfully installed react-router-dom, wrapped our app in a BrowserRouter, defined a basic set of routes, and implemented navigation using the Link component. By avoiding full-page reloads, we've taken a significant step toward a high-performance dashboard.
Up next: We will learn how to handle dynamic data by implementing URL parameters, allowing us to display specific details for individual items in our dashboard.
Work with me

Next.js Website & Landing Page Development
A blazing-fast, SEO-optimized website or landing page in Next.js — the kind that loads instantly and ranks. Design-to-code, done right.

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.