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 Router.

Параметры

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

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

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

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

Функция 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
  // ...
}

Примеры

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

Вы можете генерировать параметры для динамических сегментов выше текущего layout или страницы, но не ниже. Например, для маршрута 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 автоматически мемоизируются для одних и тех же данных во всех функциях с префиксом generate, Layouts, Pages и Server Components. React cache может быть использован, если fetch недоступен.

Генерация только подмножества параметров

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

app/blog/[slug]/page.js
// Все посты, кроме топ-10, будут возвращать 404
export const dynamicParams = false

export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
  const topPosts = posts.slice(0, 10)

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

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

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