Dynamic routes
This page explains how to create dynamic routes in Next.js.
Understanding dynamic routes
While nested routes work well for predefined paths, they become impractical when dealing with data-driven routes. Consider an e-commerce site with product pages — creating individual folders for each product would be inefficient and hard to maintain.
Directoryapp/
Directoryproducts/
Directoryiphone/
- page.tsx
/products/iphone
- page.tsx
Directorymacbook/
- page.tsx
/products/macbook
- page.tsx
Directoryipad/
- page.tsx
/products/ipad
- page.tsx
Directoryairpods/
- page.tsx
/products/airpods
(and the list goes on…)
- page.tsx
Dynamic routes allow you to create pages that can match multiple URLs using a single page component. They’re essential when building pages where the path segments are not known ahead of time.
Creating dynamic routes
To create a dynamic route in Next.js:
- Create a folder with square brackets containing the parameter name (e.g.,
[productId]
) - Add a
page.tsx
file inside this folder - Next.js will map any matching URL pattern to this page component
Directoryapp/
Directoryproducts/
Directory[productId]/
- page.tsx
/products/123
or/products/iphone
- page.tsx
Here’s a basic dynamic product details page:
export default function ProductDetails() { return <h1>Product details page</h1>;}
How dynamic routes work
When you create a folder with square brackets (e.g., [productId]
), Next.js treats it as a dynamic segment. This means:
/products/1
maps to the same page component as/products/2
- The parameter can be any string, not just numbers (e.g.,
/products/iphone
) - A single component handles all matching routes
Accessing route parameters
To access the dynamic segments of the URL, Next.js provides a params
prop to your page component. For server components, this is available as a promise that you can await.
export default async function ProductDetails({ params,}: { params: Promise<{ productId: string }>;}) { const { productId } = await params; return <h1>Details about product {productId}</h1>;}
The params
object contains key-value pairs where:
- The key is the name you specified in brackets (e.g.,
productId
) - The value is the actual URL segment
For example:
- URL
/products/iphone
→params.productId = "iphone"
- URL
/products/123
→params.productId = "123"
Dynamic routes are particularly useful for:
- Product pages in e-commerce sites
- Blog post pages
- User profiles
- Any content that follows a consistent URL pattern but has variable values