Dynamic Routing with URL Parameters in React Router
Master dynamic routing with React Router. Learn how to define parameterized paths and use the useParams hook to display unique data in your dashboard.
Previously in this course, we laid the foundation for multi-page applications by exploring the Introduction to React Router: Building Multi-Page SPAs. While static routes are great for pages like "About" or "Settings," real-world dashboards require flexible content, such as viewing specific user profiles or project details. In this lesson, we move beyond hardcoded links to implement dynamic routing, allowing our application to react to changing URL parameters.
Understanding Parameterized Paths
In a standard application, you don't create a separate route for every single item in your database. Instead, you define a pattern. A parameterized path is a route string that contains a variable segment, denoted by a colon (:).
When you define a route like /projects/:projectId, the React Router engine treats :projectId as a placeholder. When a user navigates to /projects/123, the router matches the path and extracts 123 as the value for the projectId key. This allows a single component to handle any number of individual project pages.
Extracting Data with useParams
To access these segments inside your component, React Router provides the useParams hook. This hook returns an object where the keys are the names you defined in your route path, and the values are the strings found in the current URL.
Worked Example: Building a Project Detail View
Let’s advance our dashboard project. We have a list of projects, and we want to click on one to see its specific details.
First, define the dynamic route in your main router configuration:
JSXimport { BrowserRouter, Routes, Route } from CE9178">'react-router-dom'; import ProjectDashboard from CE9178">'./ProjectDashboard'; import ProjectDetails from CE9178">'./ProjectDetails'; function App() { return ( <BrowserRouter> <Routes> <Route path="/projects" element={<ProjectDashboard />} /> {/* The :id segment is the dynamic part */} <Route path="/projects/:id" element={<ProjectDetails />} /> </Routes> </BrowserRouter> ); }
Now, implement the ProjectDetails component to consume that parameter:
JSXimport { useParams } from CE9178">'react-router-dom'; function ProjectDetails() { // useParams extracts the CE9178">'id' from the URL const { id } = useParams(); // In a real app, you'd use this ID to fetch data return ( <div> <h1>Project Details</h1> <p>Displaying data for project ID: {id}</p> </div> ); }
Hands-on Exercise
- Open your current dashboard project.
- Locate your existing project list component.
- Update your
Linkcomponents (or<a>tags if you haven't switched yet) to point to/projects/:id, replacing:idwith the actual project ID from your data source. - Create a new
ProjectDetailscomponent, add it to yourRoutesconfiguration, and useuseParamsto display the ID on the screen when a user clicks a project.
Common Pitfalls
- Forgetting the Colon: A common mistake is defining a route as
/projects/idinstead of/projects/:id. Without the colon, React Router looks for a literal path segment named "id" rather than a variable. - Stale Data: When a user navigates from
/projects/1to/projects/2, the component does not unmount; it simply re-renders with new props fromuseParams. If you are fetching data insideuseEffect, ensureidis included in your dependency array so the fetch triggers on every URL change. - Type Coercion: Parameters from the URL are always returned as strings. If your database IDs are numbers, remember to convert them (e.g.,
parseInt(id)) before performing comparisons or lookups in your state.
Recap
Dynamic routing is the backbone of any data-driven application. By defining paths with segments like :id and leveraging the useParams hook, you can create a single, reusable component that serves thousands of unique data points. This approach keeps your code DRY and your routing configuration clean, providing a seamless navigation experience as we continue building our dashboard.
Up next: We will explore Nested Routes and Layouts to maintain consistent UI structures across your application.
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 — from idea to deployed product, by an engineer who ships to production.

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.