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.

app/blog/[slug]/page.js
// Retorna 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` retornados por `generateStaticParams`
export default function Page({ params }) {
  const { slug } = params
  // ...
}

Dato importante

  • 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.
  • 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 retornar 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 a rellenar para la ruta.
  • El nombre de la propiedad es el nombre del segmento, y el valor de la propiedad es con qué debe rellenarse ese segmento.
Ruta de ejemploTipo 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` retornados por `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' }]
}

// Se generarán estáticamente tres versiones de esta página
// usando los `params` retornados por `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default function Page({ params }) {
  const { id } = 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` retornados por `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' },
  ]
}

// Se generarán estáticamente tres versiones de esta página
// usando los `params` retornados por `generateStaticParams`
// - /products/a/1
// - /products/b/2
// - /products/c/3
export default function Page({ params }) {
  const { category, product } = 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` retornados por `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'] }]
}

// Se generarán estáticamente tres versiones de esta página
// usando los `params` retornados por `generateStaticParams`
// - /product/a/1
// - /product/b/2
// - /product/c/3
export default function Page({ params }) {
  const { slug } = params
  // ...
}

Ejemplos

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 solo generar params para [category].

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

Generar params de abajo hacia arriba

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

// Generar 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: { category: string; product: string }
}) {
  // ...
}
// Generar 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 }) {
  // ...
}

Generar params de arriba hacia abajo

Generar primero los segmentos padres y usar el resultado para generar los segmentos hijos.

// Generar 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: { category: string } }) {
  // ...
}
// Generar 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 }) {
  // ...
}

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 retornados desde la función generateStaticParams padre para generar dinámicamente sus propios segmentos.

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

Dato importante: Las solicitudes fetch se memorizan 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.

Generar solo un subconjunto de params

Puedes generar un subconjunto de params para una ruta retornando un array de objetos con solo los segmentos dinámicos que quieras generar. 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.

app/blog/[slug]/page.js
// Todos los posts excepto los top 10 serán un 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,
  }))
}

Historial de versiones

VersiónCambios
v13.0.0Se introdujo generateStaticParams.