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
}

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 permite que la página se hidrate correctamente. Asegúrate de no pasar información sensible que no deba estar disponible en el cliente a través de props.

La referencia de la API de 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 almacenarse en caché por una CDN para mejorar el rendimiento
  • Los datos pueden almacenarse en caché públicamente (no específicos del usuario). Esta condición puede omitirse 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. Puedes verificar que el código dentro de getStaticProps se elimina del bundle 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 se revalida la página obsoleta, 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 se poblará 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 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,
    },
  }
}
// posts se poblará 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 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 de 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 servidor, nunca se ejecutará en el cliente. Ni siquiera se incluirá en el bundle de 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 datos de 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.

Tomemos 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 de 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 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 de API para obtener datos, entonces la API fetch() puede usarse directamente en getStaticProps para obtener datos.

Para verificar qué elimina Next.js del bundle del cliente, puedes usar la herramienta next-code-elimination.

Genera tanto HTML como JSON estáticos

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 navegas 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 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 cliente. Puedes 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 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 agregas getStaticProps como una propiedad del componente de página.

Nota importante: si has creado una app 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 en 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.