Skip to main content

Dynamic Routing in React: URL Parameters Guide

Dynamic routing enables a single route to render different content based on URL parameters. Instead of creating separate routes for every user, product, or post, define parameterized routes that render components based on IDs in the URL. Learn to use React Router's dynamic segments and prepare for accessing parameters with useParams.

Key Takeaways

  • Dynamic routing allows one route to handle multiple data items (users, products, posts) via URL parameters
  • Define URL parameters in a route path by prefixing with a colon: /users/:userId
  • A single parameterized route scales to handle unlimited items without route duplication
  • URL parameters are extracted and used in components to fetch or display the relevant data

What Is Dynamic Routing and Why Is It Essential?

In many web applications, you need pages for collections of items—users, products, blog articles, etc. Creating a separate route for each item (e.g., /users/1, /users/2, /users/3, etc.) would be impractical, repetitive, and unmaintainable.

Dynamic routing solves this by allowing a single route to handle multiple data items via URL parameters. A URL parameter is a variable part of the URL that passes data to your application. For example, /users/:userId is a dynamic route where userId is a parameter that can be any user's ID.

When a user visits /users/42, the route matches the pattern, and your component can extract the 42 parameter and render the profile for user 42. When they visit /users/100, the same route matches, and your component renders user 100's profile. This approach is scalable, maintainable, and matches how modern web applications work.

How Do You Define a Dynamic Route?

To create a dynamic route, use a colon (:) prefix in the route path to define a URL parameter.

Step 1: Create the Component

First, create a simple UserProfile component that will be used for any user:

// UserProfile.jsx
import React from 'react';

function UserProfile() {
return <h1>User Profile</h1>;
}

export default UserProfile;

For now, it's a placeholder. In the next part of this series, you'll learn how to extract the userId parameter and fetch the user's data.

Step 2: Define the Parameterized Route

In your main App.js file, import React Router components and add a dynamic route:

// App.js
import React from 'react';
import { Routes, Route, Link } from 'react-router-dom';
import Home from './Home';
import UserProfile from './UserProfile';

function App() {
return (
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/users/1">User 1</Link>
</li>
<li>
<Link to="/users/2">User 2</Link>
</li>
</ul>
</nav>

<hr />

<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:userId" element={<UserProfile />} />
</Routes>
</div>
);
}

export default App;

Code Breakdown:

  1. <Route path="/users/:userId" ... />: This route has a dynamic segment called userId. The colon indicates it's a parameter. When a user visits /users/1, /users/42, or /users/john-doe, this route matches, and userId captures the value (1, 42, or john-doe respectively).
  2. <Link to="/users/1"> and <Link to="/users/2">: These links navigate to /users/1 and /users/2. When clicked, the URL changes, the route matches, and the UserProfile component renders.

Now, when you click "User 1", the URL becomes /users/1 and the UserProfile component renders. Click "User 2", the URL becomes /users/2, and the same component renders again. Both URLs match the /users/:userId route pattern.

How Do You Define Multiple URL Parameters?

Routes can have multiple parameters. For example, a route for blog post comments:

<Route path="/posts/:postId/comments/:commentId" element={<Comment />} />

This matches URLs like /posts/5/comments/12, where postId is 5 and commentId is 12. In your component, you'd extract both parameters using the useParams hook (covered in the next part).

Best Practices for Dynamic Routes

Do:

  • Use descriptive parameter names: /users/:userId is clearer than /users/:id (if you have multiple routes).
  • Keep parameter names lowercase: Consistency with URL conventions.
  • Validate or handle missing parameters: If a user ID doesn't exist, show a 404 or error component.
  • Use optional segments only when necessary: /posts/:year/:month/:day/:slug is specific; /posts/:slug is simpler if year/month/day aren't needed.

Avoid:

  • Deep nesting without reason: /a/:id/b/:id2/c/:id3 is hard to follow; break it into logical pieces.
  • Using parameters for non-identifying data: Parameters should identify a resource; use query strings (?filter=active) for other data.
  • Changing parameter names without updating links: If you rename a parameter, all links must update accordingly.

Frequently Asked Questions

Can I have optional URL parameters?

React Router doesn't have built-in optional segment syntax. For optional parameters, use query strings instead:

// Instead of: /users/:userId/posts/:postId
// Use: /users/:userId/posts?postId=5

// Then extract the query parameter:
import { useSearchParams } from 'react-router-dom';
const [searchParams] = useSearchParams();
const postId = searchParams.get('postId');

What happens if the URL doesn't match any route?

If /users/profile/edit doesn't match any route, React Router won't render any component. You should define a catch-all route for 404 pages:

<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:userId" element={<UserProfile />} />
<Route path="*" element={<NotFound />} />
</Routes>

The path="*" route matches anything that didn't match earlier routes.

Can URL parameters be anything, or do they have to be numbers?

URL parameters are always strings, regardless of the URL. If the URL is /users/42, the userId parameter is the string "42", not the number 42. If your parameter is a numeric ID, parse it with parseInt() in your component:

const { userId } = useParams();
const id = parseInt(userId);

Use the Link component with a template string or string concatenation:

// String interpolation
<Link to={`/users/${user.id}`}>View Profile</Link>

// String concatenation
<Link to={"/users/" + user.id}>View Profile</Link>

Never hardcode URLs if they should be dynamic.

What is the difference between URL parameters and query strings?

  • URL Parameters (e.g., /users/42) identify a specific resource. They're part of the path and are required by the route definition.
  • Query Strings (e.g., /users?role=admin) filter, sort, or configure the resource. They're optional and come after the ?.

Use parameters for resource IDs; use query strings for filters and options.

Conclusion

Dynamic routing is fundamental to building scalable web applications. By defining parameterized routes, you eliminate route duplication and create a flexible architecture where one route definition handles unlimited items.

Challenge Yourself: Create a dynamic route for blog posts: /posts/:postId. Add links to three different posts and verify that the same PostDetail component renders for each.


Glossary

  • Dynamic Routing: A routing strategy where the route pattern includes parameters that are extracted from the URL at runtime.
  • URL Parameter: A variable part of a URL, defined by a colon prefix (:paramName), that captures a value from the URL.
  • Parameterized Route: A route definition that includes one or more URL parameters, allowing it to match multiple URLs.
  • Route Pattern: The path template in a route definition (e.g., /users/:userId) that determines which URLs it matches.

Further Reading