getStaticProps

Si exportas una función llamada getStaticProps (Generación de Sitios Estáticos) desde una página, Next.js pre-renderizará esta página en el momento de construcción usando las props devueltas por getStaticProps.

import type { InferGetStaticPropsType, GetStaticProps } from 'next'

type Repo = {
  name: string
  stargazers_count: number
}

export const getStaticProps = (async (context) => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}) satisfies GetStaticProps<{
  repo: Repo
}>

export default function Page({
  repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
  return repo.stargazers_count
}
export async function getStaticProps() {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}

export default function Page({ repo }) {
  return repo.stargazers_count
}

Tenga en cuenta que, independientemente del tipo de renderizado, cualquier props se pasará al componente de la página y se podrá ver en el lado del cliente en el HTML inicial. Esto es para permitir que la página se hidrate correctamente. Asegúrese de no pasar ninguna información sensible que no deba estar disponible en el cliente a través de props.

¿Cuándo debo usar getStaticProps?

Debe usar getStaticProps si:

  • Los datos necesarios para renderizar la página están disponibles en el momento de construcción, antes de la solicitud de un usuario
  • Los datos provienen de un CMS headless
  • La página debe ser pre-renderizada (para SEO) y ser muy rápida — getStaticProps genera archivos HTML y JSON, ambos pueden ser almacenados en caché por una CDN para mejorar el rendimiento
  • Los datos pueden ser almacenados en caché públicamente (no específicos del usuario). Esta condición puede evitarse en situaciones específicas usando un Middleware para reescribir la ruta.

¿Cuándo se ejecuta getStaticProps?

getStaticProps siempre se ejecuta en el servidor y nunca en el cliente. Puede validar que el código escrito dentro de getStaticProps se elimina del paquete del lado del cliente con esta herramienta.

  • getStaticProps siempre se ejecuta durante next build
  • getStaticProps se ejecuta en segundo plano cuando se usa fallback: true
  • getStaticProps se llama antes del renderizado inicial cuando se usa fallback: blocking
  • getStaticProps se ejecuta en segundo plano cuando se usa revalidate
  • getStaticProps se ejecuta bajo demanda en segundo plano cuando se usa revalidate()

Cuando se combina con Regeneración Estática Incremental, getStaticProps se ejecutará en segundo plano mientras la página obsoleta se está revalidando, y la página fresca se sirve al navegador.

getStaticProps no tiene acceso a la solicitud entrante (como parámetros de consulta o encabezados HTTP) ya que genera HTML estático. Si necesita acceso a la solicitud para su página, considere usar Middleware además de getStaticProps.

Usando getStaticProps para obtener datos de un CMS

El siguiente ejemplo muestra cómo puede obtener una lista de publicaciones de blog desde un CMS.

// posts se llenará en el momento de construcción por getStaticProps()
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// Esta función se llama en el momento de construcción en el servidor.
// No se llamará en el cliente, por lo que incluso puede hacer
// consultas directas a la base de datos.
export async function getStaticProps() {
  // Llama a un endpoint de API externo para obtener posts.
  // Puede usar cualquier biblioteca de obtención de datos
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Al devolver { props: { posts } }, el componente Blog
  // recibirá `posts` como prop en el momento de construcción
  return {
    props: {
      posts,
    },
  }
}
// posts se llenará en el momento de construcción por getStaticProps()
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// Esta función se llama en el momento de construcción en el servidor.
// No se llamará en el cliente, por lo que incluso puede hacer
// consultas directas a la base de datos.
export async function getStaticProps() {
  // Llama a un endpoint de API externo para obtener posts.
  // Puede usar cualquier biblioteca de obtención de datos
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Al devolver { props: { posts } }, el componente Blog
  // recibirá `posts` como prop en el momento de construcción
  return {
    props: {
      posts,
    },
  }
}

La referencia de API de getStaticProps cubre todos los parámetros y props que se pueden usar con getStaticProps.

Escribir código del lado del servidor directamente

Como getStaticProps solo se ejecuta en el servidor, nunca se ejecutará en el cliente. Ni siquiera se incluirá en el paquete JS para el navegador, por lo que puede escribir consultas directas a la base de datos sin que se envíen a los navegadores.

Esto significa que en lugar de obtener datos de una ruta API desde getStaticProps (que a su vez obtiene datos de una fuente externa), puede escribir el código del lado del servidor directamente en getStaticProps.

Tome el siguiente ejemplo. Se usa una ruta API para obtener algunos datos de un CMS. Luego, esa ruta API se llama directamente desde getStaticProps. Esto produce una llamada adicional, reduciendo el rendimiento. En su lugar, la lógica para obtener los datos del CMS se puede compartir usando un directorio lib/. Luego se puede compartir con getStaticProps.

lib/load-posts.js
// La siguiente función se comparte
// con getStaticProps y rutas API
// desde un directorio `lib/`
export async function loadPosts() {
  // Llama a un endpoint de API externo para obtener posts
  const res = await fetch('https://.../posts/')
  const data = await res.json()

  return data
}
pages/blog.js
// pages/blog.js
import { loadPosts } from '../lib/load-posts'

// Esta función solo se ejecuta en el servidor
export async function getStaticProps() {
  // En lugar de obtener su ruta `/api`, puede llamar a la misma
  // función directamente en `getStaticProps`
  const posts = await loadPosts()

  // Las props devueltas se pasarán al componente de página
  return { props: { posts } }
}

Alternativamente, si no está usando rutas API para obtener datos, entonces la API fetch() puede usarse directamente en getStaticProps para obtener datos.

Para verificar qué elimina Next.js del paquete del lado del cliente, puede usar la herramienta next-code-elimination.

Genera estáticamente tanto HTML como JSON

Cuando una página con getStaticProps se pre-renderiza en el momento de construcción, además del archivo HTML de la página, Next.js genera un archivo JSON que contiene el resultado de ejecutar getStaticProps.

Este archivo JSON se usará en el enrutamiento del lado del cliente a través de next/link o next/router. Cuando navega a una página que se ha pre-renderizado usando getStaticProps, Next.js obtiene este archivo JSON (precalculado en el momento de construcción) y lo usa como props para el componente de página. Esto significa que las transiciones de página del lado del cliente no llamarán a getStaticProps, ya que solo se usa el JSON exportado.

Cuando se usa Regeneración Estática Incremental, getStaticProps se ejecutará en segundo plano para generar el JSON necesario para la navegación del lado del cliente. Puede ver esto en forma de múltiples solicitudes para la misma página, sin embargo, esto es intencional y no afecta el rendimiento del usuario final.

¿Dónde puedo usar getStaticProps?

getStaticProps solo puede exportarse desde una página. No puede exportarse desde archivos que no sean páginas, _app, _document o _error.

Una de las razones de esta restricción es que React necesita tener todos los datos requeridos antes de que la página se renderice.

Además, debe exportar getStaticProps como una función independiente — no funcionará si agrega getStaticProps como una propiedad del componente de página.

Nota importante: si ha creado una aplicación personalizada, asegúrese de pasar las pageProps al componente de página como se muestra en el documento enlazado, de lo contrario las props estarán vacías.

Se ejecuta en cada solicitud en desarrollo

En desarrollo (next dev), getStaticProps se llamará en cada solicitud.

Modo de vista previa

Puede omitir temporalmente la generación estática y renderizar la página en tiempo de solicitud en lugar de en tiempo de construcción usando el Modo de vista previa. Por ejemplo, podría estar usando un CMS headless y querer previsualizar borradores antes de que se publiquen.