Dynamic routes use bracket syntax like `[id]` in folder/file names. For static generation, use `generateStaticParams` (App Router) or `getStaticPaths` (Pages Router) to define which paths should be pre-rendered at build time.
Dynamic Route Syntax:
[id] - Single dynamic segment[...slug] - Catch-all (matches any number of segments)[[...slug]] - Optional catch-all (matches zero or more)Static Generation for Dynamic Routes:
App Router:
generateStaticParams() to return all pathsPages Router:
getStaticPaths() with getStaticProps()fallback behavior:
false: 404 for unknown pathstrue: Generate on-demand, show loading'blocking': Generate on-demand, wait for HTMLOn-Demand Generation:
// app/products/[id]/page.tsx
type Props = {
params: { id: string };
};
// Generate static paths at build time
export async function generateStaticParams() {
const products = await fetch('https://api.example.com/products')
.then(res => res.json());
// Return array of params to pre-render
return products.map((product: any) => ({
id: product.id.toString(),
}));
}
// Page component
export default async function ProductPage({ params }: Props) {
const product = await fetch(
`https://api.example.com/products/${params.id}`
).then(res => res.json());
return (
<div>
<h1>{product.name}</h1>
<p>${product.price}</p>
</div>
);
}
// Output: Pre-renders /products/1, /products/2, etc.