Dynamic Routes with useParams
In this tutorial, we will learn how to create dynamic routes using useParams in React Router 7 with React 19.
Dynamic routes allow your application to respond to URL segments like IDs, slugs, or usernames.
What We Will Learn
- What dynamic routes are
- When to use dynamic routes
- How route parameters work
- Using
useParamsto read URL values - Building a real world dynamic page
- Best practices for dynamic routing
What Is a Dynamic Route
A dynamic route is a route where part of the URL is a variable.
Examples:
/users/42/posts/hello-world/products/sku-123
Instead of creating a route for every possible value, you define a placeholder.
/users/:idHere, :id is the dynamic segment.
Basic Folder Structure
We will build a small example with a list of posts and a dynamic post page.
/src
/app
app.tsx
root-layout.tsx
/pages
posts.tsx
post.tsx
main.tsx
Defining a Dynamic Route
Dynamic segments are defined with a colon.
app.tsx
// src/app/app.tsx
import { createBrowserRouter } from "react-router";
import RootLayout from "./root-layout";
import Posts from "../pages/posts";
import Post from "../pages/post";
export const router = createBrowserRouter([
{
element: <RootLayout />,
children: [
{ path: "/posts", element: <Posts /> },
{ path: "/posts/:postId", element: <Post /> },
],
},
]);postId can be any value from the URL.
Creating a List Page with Links
posts.tsx
// src/pages/posts.tsx
import { Link } from "react-router";
export default function Posts() {
const posts = [
{ id: "react-19", title: "React 19 Overview" },
{ id: "router-7", title: "React Router 7 Guide" },
];
return (
<>
<title>Posts</title>
<h1>Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link to={`/posts/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
</>
);
}Each link navigates to a dynamic URL.
Reading Route Parameters with useParams
React Router provides the useParams Hook to read dynamic segments.
post.tsx
// src/pages/post.tsx
import { useParams } from "react-router";
export default function Post() {
const { postId } = useParams();
return (
<>
<title>Post</title>
<h1>Post</h1>
<p>Post ID: {postId}</p>
</>
);
}useParams returns an object where keys match the route parameter names.
How useParams Works
If the URL is:
/posts/react-19Then:
const { postId } = useParams();postId will be:
"react-19"This value can be used to:
- Fetch data
- Select items
- Control rendering
Using useParams with the use API
Dynamic routes are often used to fetch data.
In React 19, the use API makes this simple.
Example with Data Fetching
// src/pages/post.tsx
import { use } from "react";
import { useParams } from "react-router";
async function fetchPost(id: string) {
const res = await fetch(`https://api.example.com/posts/${id}`);
return res.json();
}
export default function Post() {
const { postId } = useParams();
const post = use(fetchPost(postId!));
return (
<>
<title>{post.title}</title>
<h1>{post.title}</h1>
<p>{post.content}</p>
</>
);
}The route controls the data that loads.
Handling Missing Parameters
Route params are always strings and can be undefined.
A simple guard improves safety.
if (!postId) {
return <p>Post not found</p>;
}This prevents runtime errors.
Best Practices for Dynamic Routes
- Keep parameter names meaningful
- Treat route params as strings
- Validate params before using them
- Use dynamic routes for content driven pages
- Avoid deeply nested dynamic segments early
Dynamic routes should be predictable and readable.
Common Mistakes
- Forgetting the colon in route paths
- Assuming params are numbers
- Overloading routes with too many dynamic segments
- Fetching data without validating params
Conclusion
Dynamic routes with useParams are essential for real world React applications.
They allow your UI, URLs, and data to work together naturally.
Once you understand how route parameters flow into components, building content driven apps becomes simple and scalable.