generateStaticParams
Функция generateStaticParams
может использоваться в сочетании с динамическими сегментами маршрутов для статической генерации маршрутов во время сборки, а не по запросу.
// Возвращает список `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 async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
// ...
}
// Возвращает список `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 async function Page({ params }) {
const { slug } = await params
// ...
}
Полезно знать:
- Вы можете использовать опцию конфигурации сегмента
dynamicParams
для управления поведением при посещении динамического сегмента, который не был сгенерирован с помощьюgenerateStaticParams
.- Для повторной валидации (ISR) путей во время выполнения необходимо либо вернуть пустой массив из
generateStaticParams
, либо использоватьexport const dynamic = 'force-static'
.- В режиме
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 async function Page({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
// ...
}
export function generateStaticParams() {
return [{ id: '1' }, { id: '2' }, { id: '3' }]
}
// Три версии этой страницы будут статически сгенерированы
// с использованием `params`, возвращенных `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default async function Page({ params }) {
const { id } = await 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 async function Page({
params,
}: {
params: Promise<{ category: string; product: string }>
}) {
const { category, product } = await 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 async function Page({ params }) {
const { category, product } = await 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 async function Page({
params,
}: {
params: Promise<{ slug: string[] }>
}) {
const { slug } = await 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 async function Page({ params }) {
const { slug } = await params
// ...
}
Примеры
Статический рендеринг
Все пути во время сборки
Для статического рендеринга всех путей во время сборки передайте полный список путей в generateStaticParams
:
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
Подмножество путей во время сборки
Для статического рендеринга подмножества путей во время сборки, а остальных - при первом посещении во время выполнения, верните частичный список путей:
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
// Рендеринг первых 10 постов во время сборки
return posts.slice(0, 10).map((post) => ({
slug: post.slug,
}))
}
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
// Рендеринг первых 10 постов во время сборки
return posts.slice(0, 10).map((post) => ({
slug: post.slug,
}))
}
Затем, используя опцию конфигурации сегмента dynamicParams
, вы можете управлять поведением при посещении динамического сегмента, который не был сгенерирован с помощью generateStaticParams
.
// Все посты, кроме топ-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,
}))
}
// Все посты, кроме топ-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,
}))
}
Все пути во время выполнения
Для статического рендеринга всех путей при первом посещении верните пустой массив (никакие пути не будут рендериться во время сборки) или используйте export const dynamic = 'force-static'
:
export async function generateStaticParams() {
return []
}
Полезно знать: Вы всегда должны возвращать массив из
generateStaticParams
, даже если он пустой. В противном случае маршрут будет рендериться динамически.
export const dynamic = 'force-static'
Отключение рендеринга для неуказанных путей
Чтобы предотвратить статический рендеринг неуказанных путей во время выполнения, добавьте опцию export const dynamicParams = false
в сегменте маршрута. При использовании этой опции конфигурации будут обслуживаться только пути, предоставленные generateStaticParams
, а неуказанные маршруты будут возвращать 404 или соответствовать (в случае catch-all маршрутов).
Несколько динамических сегментов в маршруте
Вы можете генерировать параметры для динамических сегментов выше текущего 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: Promise<{ 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: Promise<{ 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: Promise<{ 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. Reactcache
может быть использован, еслиfetch
недоступен.
История версий
Версия | Изменения |
---|---|
v13.0.0 | Добавлена функция generateStaticParams . |