> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/vercel/next.js/llms.txt
> Use this file to discover all available pages before exploring further.

# generateStaticParams

> API reference for the generateStaticParams function, used to statically generate routes at build time for dynamic segments.

`generateStaticParams` can be used with [dynamic route segments](/app/core-concepts/routing) to **statically generate** routes at build time instead of on-demand at request time.

It can be exported from:

* [Pages](/api-reference/file-conventions/page) (`page.tsx`)
* [Layouts](/api-reference/file-conventions/layout) (`layout.tsx`)
* [Route Handlers](/api-reference/file-conventions/route) (`route.ts`)

```typescript app/blog/[slug]/page.tsx theme={null}
export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then((res) =>
    res.json()
  )

  return posts.map((post: { slug: string }) => ({
    slug: post.slug,
  }))
}

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  return <h1>{slug}</h1>
}
```

## Parameters

<ParamField body="params" type="object">
  When multiple dynamic segments in a route each export `generateStaticParams`, the child function receives the `params` object generated by the parent. This allows child segments to generate their own params based on parent values.
</ParamField>

## Returns

An array of objects where each object represents the populated dynamic segments of a single route.

* Each property key is the segment name.
* Each property value is the string value (or array of strings for catch-all segments) to fill in.

| Route                            | Return type                               |
| -------------------------------- | ----------------------------------------- |
| `/product/[id]`                  | `{ id: string }[]`                        |
| `/products/[category]/[product]` | `{ category: string; product: string }[]` |
| `/products/[...slug]`            | `{ slug: string[] }[]`                    |

## Good to know

* Use [`dynamicParams`](/api-reference/config/next-config-js) to control what happens when a dynamic segment not covered by `generateStaticParams` is visited.
* Return an empty array (or use `export const dynamic = 'force-static'`) to render all paths at runtime (ISR).
* During `next dev`, `generateStaticParams` is called when you navigate to a route.
* During `next build`, it runs before the corresponding Layouts and Pages are generated.
* During revalidation (ISR), `generateStaticParams` is not called again.
* `generateStaticParams` replaces [`getStaticPaths`](/pages/building/data-fetching) from the Pages Router.
* `fetch` requests in `generateStaticParams` are automatically [memoized](/app/core-concepts/routing#memoization) across all `generate`-prefixed functions, Layouts, Pages, and Server Components.

## Examples

### Single dynamic segment

```typescript app/product/[id]/page.tsx theme={null}
export function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }, { id: '3' }]
}

// Generates:
// - /product/1
// - /product/2
// - /product/3
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  return <h1>Product {id}</h1>
}
```

### Multiple dynamic segments

```typescript app/products/[category]/[product]/page.tsx theme={null}
export function generateStaticParams() {
  return [
    { category: 'electronics', product: 'laptop' },
    { category: 'clothing', product: 'shirt' },
  ]
}

export default async function Page({
  params,
}: {
  params: Promise<{ category: string; product: string }>
}) {
  const { category, product } = await params
  return <h1>{category} / {product}</h1>
}
```

### Catch-all segment

```typescript app/product/[...slug]/page.tsx theme={null}
export function generateStaticParams() {
  return [
    { slug: ['electronics', 'laptops'] },
    { slug: ['clothing', 'shirts'] },
  ]
}

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string[] }>
}) {
  const { slug } = await params
  return <h1>{slug.join(' / ')}</h1>
}
```

### All paths at build time

```typescript app/blog/[slug]/page.tsx theme={null}
export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then((res) =>
    res.json()
  )
  return posts.map((post: { slug: string }) => ({ slug: post.slug }))
}
```

### Subset of paths, rest at runtime

```typescript app/blog/[slug]/page.tsx theme={null}
export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then((res) =>
    res.json()
  )
  // Render only the first 10 posts at build time
  return posts.slice(0, 10).map((post: { slug: string }) => ({ slug: post.slug }))
}
```

### Disabling unspecified paths (404)

```typescript app/blog/[slug]/page.tsx theme={null}
// All slugs not in the list will return 404
export const dynamicParams = false

export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then((res) =>
    res.json()
  )
  return posts.slice(0, 10).map((post: { slug: string }) => ({ slug: post.slug }))
}
```

### Multiple dynamic segments (top-down)

Generate parent segment params first, then use them in child `generateStaticParams`:

```typescript app/products/[category]/layout.tsx theme={null}
export async function generateStaticParams() {
  const products = await fetch('https://api.example.com/products').then(
    (res) => res.json()
  )
  return products.map((p: { category: { slug: string } }) => ({
    category: p.category.slug,
  }))
}
```

```typescript app/products/[category]/[product]/page.tsx theme={null}
import type { LayoutProps } from 'next'

export async function generateStaticParams({
  params: { category },
}: {
  params: Awaited<LayoutProps<'/products/[category]'>['params']>
}) {
  const products = await fetch(
    `https://api.example.com/products?category=${category}`
  ).then((res) => res.json())

  return products.map((p: { id: string }) => ({ product: p.id }))
}
```

## Version history

| Version   | Changes                            |
| --------- | ---------------------------------- |
| `v13.0.0` | `generateStaticParams` introduced. |
