generateStaticParams

La función generateStaticParams puede usarse en combinación con segmentos de ruta dinámicos para generar estáticamente rutas en tiempo de compilación en lugar de bajo demanda en tiempo de solicitud.

// Devuelve una lista de `params` para poblar el segmento dinámico [slug]
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())

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

// Se generarán estáticamente múltiples versiones de esta página
// usando los `params` devueltos por `generateStaticParams`
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  // ...
}

Es bueno saberlo:

  • Puedes usar la opción de configuración de segmento dynamicParams para controlar qué sucede cuando se visita un segmento dinámico que no fue generado con generateStaticParams.
  • Debes devolver un array vacío desde generateStaticParams o utilizar export const dynamic = 'force-static' para revalidar (ISR) rutas en tiempo de ejecución.
  • Durante next dev, generateStaticParams se llamará cuando navegues a una ruta.
  • Durante next build, generateStaticParams se ejecuta antes de que se generen los Layouts o Pages correspondientes.
  • Durante la revalidación (ISR), generateStaticParams no se volverá a llamar.
  • generateStaticParams reemplaza la función getStaticPaths en el Enrutador de Páginas.

Parámetros

options.params (opcional)

Si múltiples segmentos dinámicos en una ruta usan generateStaticParams, la función generateStaticParams hija se ejecuta una vez por cada conjunto de params que genera el padre.

El objeto params contiene los params poblados desde el generateStaticParams padre, que pueden usarse para generar los params en un segmento hijo.

Retorno

generateStaticParams debe devolver un array de objetos donde cada objeto representa los segmentos dinámicos poblados de una sola ruta.

  • Cada propiedad en el objeto es un segmento dinámico que se completará para la ruta.
  • El nombre de la propiedad es el nombre del segmento, y el valor de la propiedad es con qué se debe completar ese segmento.
Ejemplo de RutaTipo de Retorno de generateStaticParams
/product/[id]{ id: string }[]
/products/[category]/[product]{ category: string, product: string }[]
/products/[...slug]{ slug: string[] }[]

Segmento Dinámico Único

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

// Se generarán estáticamente tres versiones de esta página
// usando los `params` devueltos por `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  // ...
}

Múltiples Segmentos Dinámicos

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

// Se generarán estáticamente tres versiones de esta página
// usando los `params` devueltos por `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
  // ...
}

Segmento Dinámico Catch-all

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

// Se generarán estáticamente tres versiones de esta página
// usando los `params` devueltos por `generateStaticParams`
// - /product/a/1
// - /product/b/2
// - /product/c/3
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string[] }>
}) {
  const { slug } = await params
  // ...
}

Ejemplos

Renderizado Estático

Todas las rutas en tiempo de compilación

Para renderizar estáticamente todas las rutas en tiempo de compilación, proporciona la lista completa de rutas a generateStaticParams:

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

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

Subconjunto de rutas en tiempo de compilación

Para renderizar estáticamente un subconjunto de rutas en tiempo de compilación, y el resto la primera vez que se visiten en tiempo de ejecución, devuelve una lista parcial de rutas:

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

  // Renderiza los primeros 10 posts en tiempo de compilación
  return posts.slice(0, 10).map((post) => ({
    slug: post.slug,
  }))
}

Luego, usando la opción de configuración de segmento dynamicParams, puedes controlar qué sucede cuando se visita un segmento dinámico que no fue generado con generateStaticParams.

// Todos los posts excepto los 10 primeros devolverán 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,
  }))
}

Todas las rutas en tiempo de ejecución

Para renderizar estáticamente todas las rutas la primera vez que se visiten, devuelve un array vacío (no se renderizarán rutas en tiempo de compilación) o utiliza export const dynamic = 'force-static':

app/blog/[slug]/page.js
export async function generateStaticParams() {
  return []
}

Es bueno saberlo: Siempre debes devolver un array desde generateStaticParams, incluso si está vacío. De lo contrario, la ruta se renderizará dinámicamente.

app/changelog/[slug]/page.js
export const dynamic = 'force-static'

Deshabilitar renderizado para rutas no especificadas

Para evitar que las rutas no especificadas se rendericen estáticamente en tiempo de ejecución, añade la opción export const dynamicParams = false en un segmento de ruta. Cuando se usa esta configuración, solo se servirán las rutas proporcionadas por generateStaticParams, y las rutas no especificadas devolverán 404 o coincidirán (en el caso de rutas catch-all).

Múltiples Segmentos Dinámicos en una Ruta

Puedes generar params para segmentos dinámicos por encima del layout o página actual, pero no por debajo. Por ejemplo, dada la ruta app/products/[category]/[product]:

  • app/products/[category]/[product]/page.js puede generar params para ambos [category] y [product].
  • app/products/[category]/layout.js puede generar params solo para [category].

Hay dos enfoques para generar params para una ruta con múltiples segmentos dinámicos:

Generar params de abajo hacia arriba

Genera múltiples segmentos dinámicos desde el segmento de ruta hijo.

// Genera segmentos para ambos [category] y [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 }>
}) {
  // ...
}

Generar params de arriba hacia abajo

Genera primero los segmentos padres y usa el resultado para generar los segmentos hijos.

// Genera segmentos para [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 }>
}) {
  // ...
}

La función generateStaticParams de un segmento hijo se ejecuta una vez por cada segmento que genera un generateStaticParams padre.

La función generateStaticParams hija puede usar los params devueltos desde la función generateStaticParams padre para generar dinámicamente sus propios segmentos.

// Genera segmentos para [product] usando los `params` pasados desde
// la función `generateStaticParams` del segmento padre
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 }>
}) {
  // ...
}

Es bueno saberlo: Las solicitudes fetch se memoizan automáticamente para los mismos datos en todas las funciones con prefijo generate, Layouts, Pages y Componentes de Servidor. Se puede usar cache de React si fetch no está disponible.

Historial de Versiones

VersiónCambios
v13.0.0Se introdujo generateStaticParams.