Cómo usar getStaticPaths en Astro para generar páginas estáticas desde datos

DUGLAS MORENODUGLAS MORENO 👁 17

Introducción

Astro se ha posicionado como uno de los frameworks más interesantes para construir sitios Jamstack gracias a su enfoque de "islands architecture" y su capacidad para generar contenido totalmente estático en tiempo de compilación. Cuando trabajamos con datos externos — ya sea un archivo JSON, una colección de Markdown o una API — necesitamos indicarle a Astro qué rutas debe pre‑renderizar antes de servir el sitio. Esa tarea la cumple la función especial getStaticPaths.

En este artículo aprenderás:

  • Qué es getStaticPaths y cuándo es necesario definirla.
  • Cómo estructurar los datos y devolver un array de objetos params que Astro interpreta como rutas.
  • Ejemplos concretos con datos locales (JSON y Markdown) y con una simulación de llamada a una API externa.
  • Qué salida HTML se genera y cómo verificarla en el build.
  • Buenas prácticas, errores comunes y tips para optimizar el proceso.

Al final tendrás un patrón reutilizable que podrás aplicar a cualquier proyecto Astro que requiera generación dinámica de páginas estáticas.


¿Qué es getStaticPaths y por qué existe?

En Astro, cada archivo .astro dentro de src/pages/ se convierte automáticamente en una ruta basada en su nombre de archivo. Por ejemplo, src/pages/blog.astro genera /blog.htmly se sirve en la ruta/blog. Sin embargo, cuando queremos crear **rutas dinámicas** — como /blog/post‑slug` donde el slug proviene de un dato externo — Astro no puede inferir esas rutas solo por el nombre del archivo.

Para resolverlo, Astro busca una función exportada llamada getStaticPaths dentro del componente de página. Si la encuentra, ejecuta esa función durante el proceso de build y utiliza el array que devuelve para determinar cuántas variantes de la página deben ser pre‑renderizadas.

La firma esperada es:

// src/pages/[slug].astro
export async function getStaticPaths() {
  return [
    { params: { slug: 'primer-post' } },
    { params: { slug: 'segundo-post' } },
    // …
  ]
}

Cada objeto del array debe contener una propiedad params cuyas claves coincidan con los parámetros de la ruta (en el ejemplo, slug). Astro luego renderiza el componente tantas veces como objetos haya, pasando esos parámetros como propiedades al componente.


Estructura de un proyecto de ejemplo

Vamos a trabajar con un proyecto sencillo que tiene:

  • Una colección de artículos en formato Markdown dentro de src/content/blog/.
  • Un archivo data/posts.json con la misma información en JSON (para mostrar la alternativa).
  • Una página dinámica src/pages/blog/[slug].astro que mostrará el artículo.

La estructura de carpetas será:

my-astro-blog/
├── src/
│   ├── pages/
│   │   └── blog/
│   │       └── [slug].astro
│   └── content/
│       └── blog/
│           ├── primer-post.md
│           └── segundo-post.md
└── astro.config.mjs

Ejemplo 1: Datos en Markdown (con import.meta.glob)

Astro permite importar dinámicamente todos los archivos de una carpeta mediante import.meta.glob. Esta característica es perfecta para obtener la lista de slugs a partir de los nombres de archivo.

Paso 1: Leer los archivos Markdown

// src/pages/blog/[slug].astro
---
export async function getStaticPaths() {
  // Importamos todos los .md de src/content/blog/
  const modules = import.meta.glob('../content/blog/*.md', { eager: true });

  const paths = [];
  for (const [filePath, module] of Object.entries(modules)) {
    // El nombre del archivo sin extensión es nuestro slug
    const slug = filePath.split('/').pop().replace('.md', '');
    paths.push({ params: { slug } });
  }

  return paths;
}
---

<!-- El resto del componente recibe el slug como propiedad -->
<div>
  <h1>Artículo: {Astro.params.slug}</h1>
  <p>Este es el contenido estático generado para el slug "{Astro.params.slug}".

Comentarios (0)

Sé el primero en comentar.

Dejá tu comentario