Dynamic routes in React Router match a whole family of URLs with one route. A segment that starts with a colon, like :productId, captures that part of the URL. The useParams hook reads the captured value inside the component.
For a shop, one route serves /products/1, /products/2, and every other id.
Declare a dynamic segment
Add a colon segment to the route path, and React Router captures whatever appears in that position. The name after the colon becomes the parameter key.
<Routes>
<Route path="products" element={<Products />} />
<Route path="products/:productId" element={<Product />} />
</Routes>The second route matches /products/1, /products/42, and any other value in that position. The static products route still matches /products on its own.
Read the parameter with useParams
Inside the matched component, call useParams. It returns an object whose keys are the segment names from the path.
import { useParams } from "react-router";
export default function Product() {
const { productId } = useParams();
return <h1>Product {productId}</h1>;
}For the URL /products/42, productId is the string "42". Every parameter arrives as a string, so convert with Number(productId) before doing math or comparisons.
One component now serves every product instead of writing a route per id, and the id arrives through the URL so the page is shareable.
Link to a dynamic route
Build the target path from data. A Link whose to prop contains the id opens that product.
import { Link } from "react-router";
export default function ProductLink({ id, name }) {
return <Link to={`/products/${id}`}>{name}</Link>;
}The to prop becomes /products/1 when id is 1. This is how a list page turns a row of products into a set of links, and it pairs with programmatic navigation with useNavigate. Any data source works here, including fetched records, so the list and the detail page stay in sync through the URL.
Multiple parameters and catch-all segments
A route can capture several segments at once. This path exposes two keys from useParams.
<Route path="posts/:postId/comments/:commentId" element={<Comment />} />Inside Comment, both postId and commentId are available. A catch-all segment ending in * captures everything after the slash, including more slashes, which suits file browsers and nested paths.
Keep segment names unique in one path. A repeated name lets the later value overwrite the earlier one in the params object.
Dynamic segments also work inside nested routes, where a child captures a changing value after the parent prefix. That combination is covered in how to create nested routes with React Router.
Common mistakes
Most dynamic route bugs come from treating a URL string as a number or from a missing colon.
- Reading a parameter as a number without converting it first.
- Forgetting the colon, which turns the segment into a literal path instead of a parameter.
- Using the array index as a key for a list of dynamically linked items.
Rune AI
Key Insights
- Add a colon segment to the route path to capture part of the URL.
- Read parameters with the useParams hook.
- Convert parameter strings before using them as numbers.
- Build dynamic links by inserting values into the to prop.
Frequently Asked Questions
What type does useParams return?
Can one route capture multiple parameters?
What is a catch-all segment?
Conclusion
Dynamic routes match many URLs with one path. Add a colon segment like :productId, read it with useParams, and build links by inserting values into the path. Remember that parameters always arrive as strings.
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.