Skip to content
C.W.K.
Stream
Lesson 08 of 09 · published

generateStaticParams

~18 min · SSG, dynamic routes, build time

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Pre-render dynamic routes at build time

generateStaticParams is the App Router's equivalent of getStaticPaths. Export it from a dynamic route, return the list of params to pre-build, and Next.js generates static HTML for each at build time.

Default behavior for unknown params

Paths not in your list render on demand and get cached. Set export const dynamicParams = false to 404 unknown slugs instead.

Multi-level dynamic segments

For nested dynamic segments, return objects that fill in all segments. The function runs once at build; it doesn't have to enumerate every combination — only the ones you want pre-built.

Prebuild the dynamic paths whose first visit matters most. Use traffic and editorial importance to choose the list, leave the long tail for on-demand rendering, and set dynamicParams = false only when unknown identifiers are truly invalid.

Prebuilding everything moves runtime cost into every deployment and scales with the catalog. Prebuilding nothing makes the first visitor to each path pay. A measured hybrid usually gives the best deployment and request profile. Count generated pages, build duration, and artifact size as the data set grows. Compare first and second requests for an unlisted path, then disable dynamic params. Include deletion behavior so removed content does not survive as an old static page.

Code

Pre-build blog posts·tsx
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const slugs = await getAllPostSlugs();
  return slugs.map((slug) => ({ slug }));
}

export default async function BlogPost({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await fetchPost(slug);
  return <article dangerouslySetInnerHTML={{ __html: post.html }} />;
}
Lock unknown paths to 404·tsx
export const dynamicParams = false; // 404 for slugs not in generateStaticParams

export async function generateStaticParams() {
  return [{ slug: 'hello' }, { slug: 'world' }];
}
Two-level dynamic·tsx
// app/[locale]/blog/[slug]/page.tsx
export async function generateStaticParams() {
  return [
    { locale: 'en', slug: 'hello' },
    { locale: 'ko', slug: 'hello' },
    { locale: 'en', slug: 'world' },
  ];
}

External links

Exercise

Add generateStaticParams to a blog or docs route. Build the app and inspect the build output: count how many pages were pre-rendered and confirm unknown slugs still render at runtime.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.