Routing, Navigation, and Dynamic SegmentsLesson 2.1
How to create dynamic route segments in Next.js App Router
dynamic segments, bracket syntax, params prop, generateStaticParams, catch-all routes, optional catch-all, slug patterns
Dynamic Segments with Brackets
Wrap a folder name in square brackets to make it a dynamic segment. The folder name becomes a parameter accessible in the page component via the params prop.
// app/products/[id]/page.tsx
export default async function ProductPage({
params,
}: {
params: { id: string }
}) {
const product = await fetch(`/api/products/${params.id}`).then(r => r.json())
return <h1>{product.name}</h1>
}Catch-All Segments
Use [...slug] to capture multiple path segments as an array:
// app/docs/[...slug]/page.tsx
// Matches: /docs/a, /docs/a/b, /docs/a/b/c
export default function DocsPage({ params }: { params: { slug: string[] } }) {
return <p>{params.slug.join('/')}</p>
}Use [[...slug]] (double brackets) to also match the parent route with no segments.
generateStaticParams for Static Generation
To pre-render dynamic routes at build time, export generateStaticParams:
export async function generateStaticParams() {
const products = await fetch('/api/products').then(r => r.json())
return products.map((p: { id: string }) => ({ id: p.id }))
}This tells Next.js which values to pre-render. At build time, Next.js calls generateStaticParams, gets the list, and generates one static HTML file per item. Requests to unlisted IDs can be handled dynamically or return 404.
