generateStaticParams

Функция generateStaticParams может использоваться в сочетании с динамическими сегментами маршрутов для статической генерации маршрутов во время сборки, а не по запросу.

app/blog/[slug]/page.js
// Возвращает список `params` для заполнения динамического сегмента [slug]
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())

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

// Несколько версий этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
export default function Page({ params }) {
  const { slug } = params
  // ...
}

Полезно знать

  • Вы можете использовать опцию конфигурации сегмента dynamicParams для управления поведением при посещении динамического сегмента, который не был сгенерирован с помощью generateStaticParams.
  • В режиме next dev функция generateStaticParams будет вызываться при переходе на маршрут.
  • Во время next build функция generateStaticParams выполняется до генерации соответствующих макетов (Layouts) или страниц (Pages).
  • При ревалидации (ISR) функция generateStaticParams не вызывается повторно.
  • generateStaticParams заменяет функцию getStaticPaths в маршрутизаторе Pages.

Параметры

options.params (опционально)

Если несколько динамических сегментов в маршруте используют generateStaticParams, дочерняя функция generateStaticParams выполняется один раз для каждого набора params, сгенерированного родительским компонентом.

Объект params содержит заполненные параметры из родительской функции generateStaticParams, которые могут быть использованы для генерации параметров в дочернем сегменте.

Возвращаемое значение

Функция generateStaticParams должна возвращать массив объектов, где каждый объект представляет заполненные динамические сегменты одного маршрута.

  • Каждое свойство объекта — это динамический сегмент, который нужно заполнить для маршрута.
  • Имя свойства соответствует имени сегмента, а значение свойства — это значение, которым должен быть заполнен сегмент.
Пример маршрутаТип возвращаемого значения generateStaticParams
/product/[id]{ id: string }[]
/products/[category]/[product]{ category: string, product: string }[]
/products/[...slug]{ slug: string[] }[]

Один динамический сегмент

export function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }, { id: '3' }]
}

// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default function Page({ params }: { params: { id: string } }) {
  const { id } = params
  // ...
}
export function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }, { id: '3' }]
}

// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default function Page({ params }) {
  const { id } = params
  // ...
}

Несколько динамических сегментов

export function generateStaticParams() {
  return [
    { category: 'a', product: '1' },
    { category: 'b', product: '2' },
    { category: 'c', product: '3' },
  ]
}

// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
// - /products/a/1
// - /products/b/2
// - /products/c/3
export default function Page({
  params,
}: {
  params: { category: string; product: string }
}) {
  const { category, product } = params
  // ...
}
export function generateStaticParams() {
  return [
    { category: 'a', product: '1' },
    { category: 'b', product: '2' },
    { category: 'c', product: '3' },
  ]
}

// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
// - /products/a/1
// - /products/b/2
// - /products/c/3
export default function Page({ params }) {
  const { category, product } = params
  // ...
}

Catch-all динамический сегмент

export function generateStaticParams() {
  return [{ slug: ['a', '1'] }, { slug: ['b', '2'] }, { slug: ['c', '3'] }]
}

// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
// - /product/a/1
// - /product/b/2
// - /product/c/3
export default function Page({ params }: { params: { slug: string[] } }) {
  const { slug } = params
  // ...
}
export function generateStaticParams() {
  return [{ slug: ['a', '1'] }, { slug: ['b', '2'] }, { slug: ['c', '3'] }]
}

// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращённых функцией `generateStaticParams`
// - /product/a/1
// - /product/b/2
// - /product/c/3
export default function Page({ params }) {
  const { slug } = params
  // ...
}

Примеры

Несколько динамических сегментов в маршруте

Вы можете генерировать параметры для динамических сегментов выше текущего макета или страницы, но не ниже. Например, для маршрута app/products/[category]/[product]:

  • app/products/[category]/[product]/page.js может генерировать параметры и для [category], и для [product].
  • app/products/[category]/layout.js может генерировать параметры только для [category].

Существует два подхода к генерации параметров для маршрута с несколькими динамическими сегментами:

Генерация параметров снизу вверх

Генерация нескольких динамических сегментов из дочернего сегмента маршрута.

// Генерация сегментов для [category] и [product]
export async function generateStaticParams() {
  const products = await fetch('https://.../products').then((res) => res.json())

  return products.map((product) => ({
    category: product.category.slug,
    product: product.id,
  }))
}

export default function Page({
  params,
}: {
  params: { category: string; product: string }
}) {
  // ...
}
// Генерация сегментов для [category] и [product]
export async function generateStaticParams() {
  const products = await fetch('https://.../products').then((res) => res.json())

  return products.map((product) => ({
    category: product.category.slug,
    product: product.id,
  }))
}

export default function Page({ params }) {
  // ...
}

Генерация параметров сверху вниз

Сначала генерируются родительские сегменты, а затем их результат используется для генерации дочерних сегментов.

// Генерация сегментов для [category]
export async function generateStaticParams() {
  const products = await fetch('https://.../products').then((res) => res.json())

  return products.map((product) => ({
    category: product.category.slug,
  }))
}

export default function Layout({ params }: { params: { category: string } }) {
  // ...
}
// Генерация сегментов для [category]
export async function generateStaticParams() {
  const products = await fetch('https://.../products').then((res) => res.json())

  return products.map((product) => ({
    category: product.category.slug,
  }))
}

export default function Layout({ params }) {
  // ...
}

Функция generateStaticParams дочернего сегмента маршрута выполняется один раз для каждого сегмента, сгенерированного родительской функцией generateStaticParams.

Дочерняя функция generateStaticParams может использовать параметры params, возвращённые родительской функцией generateStaticParams, для динамической генерации собственных сегментов.

// Генерация сегментов для [product] с использованием `params`,
// переданных из родительской функции `generateStaticParams`
export async function generateStaticParams({
  params: { category },
}: {
  params: { category: string }
}) {
  const products = await fetch(
    `https://.../products?category=${category}`
  ).then((res) => res.json())

  return products.map((product) => ({
    product: product.id,
  }))
}

export default function Page({
  params,
}: {
  params: { category: string; product: string }
}) {
  // ...
}
// Генерация сегментов для [product] с использованием `params`,
// переданных из родительской функции `generateStaticParams`
export async function generateStaticParams({ params: { category } }) {
  const products = await fetch(
    `https://.../products?category=${category}`
  ).then((res) => res.json())

  return products.map((product) => ({
    product: product.id,
  }))
}

export default function Page({ params }) {
  // ...
}

Полезно знать: Запросы fetch автоматически мемоизируются для одних и тех же данных между generateMetadata, generateStaticParams, макетами (Layouts), страницами (Pages) и серверными компонентами. React cache может быть использован, если fetch недоступен.

История версий

ВерсияИзменения
v13.0.0Добавлена функция generateStaticParams.