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
}

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

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

¿Cuándo debería usar getStaticProps?

Deberías 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 omitirse en ciertas 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. Puedes verificar 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 cabeceras HTTP) ya que genera HTML estático. Si necesitas acceso a la solicitud para tu página, considera usar Middleware además de getStaticProps.

Usando getStaticProps para obtener datos de un CMS

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

// posts será poblado 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 lado del cliente, por lo que incluso puedes hacer
// consultas directas a la base de datos.
export async function getStaticProps() {
  // Llama a un endpoint de API externo para obtener las publicaciones.
  // Puedes 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 la API getStaticProps cubre todos los parámetros y props que pueden usarse con getStaticProps.

Escribir código del lado del servidor directamente

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

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

Toma el siguiente ejemplo. Se usa una ruta de API para obtener algunos datos de un CMS. Luego, esa ruta de 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 puede compartirse usando un directorio lib/. Luego puede compartirse 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 publicaciones
  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 lado del servidor
export async function getStaticProps() {
  // En lugar de obtener tu ruta `/api` puedes llamar a la misma
  // función directamente en `getStaticProps`
  const posts = await loadPosts()

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

Alternativamente, si no estás 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, puedes usar la herramienta next-code-elimination.

Genera estáticamente tanto HTML como JSON

Cuando una página con getStaticProps es pre-renderizada 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 navegas a una página que está pre-renderizada usando getStaticProps, Next.js obtiene este archivo JSON (precalculado en el momento de construcción) y lo usa como props para el componente de la 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. Puedes ver esto en forma de múltiples solicitudes hechas 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 puedes exportarlo 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, debes exportar getStaticProps como una función independiente — no funcionará si añades getStaticProps como una propiedad del componente de la página.

Nota importante: si has creado una aplicación personalizada, asegúrate de pasar las pageProps al componente de la 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

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