Script Valley
Next.js: Full-Stack React Applications
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.

Up next

How to navigate between pages using the Next.js Link component

Sign in to track progress