Hasta ahora, si queríamos crear una página nueva, creábamos un archivo nuevo: contacto.astro, nosotros.astro. Esto es lo que llamamos enrutamiento estático.
Pero, ¿qué pasa si tenemos una tienda online con 300 productos? ¿O una web como esta con mas de 5.000 artículos? No es viable crear 5.000 archivos .astro a mano.
Necesitamos una forma de crear un molde y un mecanismo para decirle a Astro:
Usa este molde para generar una página por cada uno de los elementos que yo te diga
Por supuesto en Astro el molde será un componente, y el mecanismo para generarlos en lotes son las rutas dinámicas y la función getStaticPaths.
La sintaxis de corchetes [param]
Para generar un enturado dinámico usamos corchetes en el nombre del archivo. Lo que pongamos dentro de los corchetes será el nombre del parámetro variable.
Por ejemplo. si creamos el archivo: src/pages/producto/[id].astro
Este archivo podrá generar rutas como:
/producto/1/producto/zapatillas-nike/producto/abc-123
¿Qué rutas va a generar? Depende de los valores posibles de [id], que definimos con getStaticPaths 👇
El valor que ocupe el parámetro, en este caso [id], será accesible dentro del código.
const { id } = Astro.params;
La función getStaticPaths
Astro no puede adivinar qué IDs tiene tu web. Tú tienes que decirle los posibles valores (por ejemplo, qué productos tienes en tu base de datos).
Para eso exportamos una función obligatoria llamada getStaticPaths.
Como Astro es (por defecto) un generador de sitios estáticos (SSG), necesita saber en el momento de la compilación (build time) exactamente qué páginas van a existir.
La función getStaticPaths solo se ejecuta en el momento de construir el sitio (npm run build). No se ejecuta en el navegador del usuario.
Veamos un ejemplo básico. Supongamos que quieres hacer una web que habla sobre perros. Un apartado es hablar sobre las distintas razas de perros.
Así que haces un componente llamado src/pages/perros/[raza].astro:
---
export function getStaticPaths() {
// Esta función DEBE devolver un array de objetos
// Cada objeto representa una página que se va a generar
return [
{ params: { raza: 'labrador' } },
{ params: { raza: 'pastor-aleman' } },
{ params: { raza: 'caniche' } },
];
}
// Para acceder al parámetro de la URL actual:
const { raza } = Astro.params;
---
<h1>Información sobre el {raza}</h1>
En la funcion getStaticPaths has específicado las tres páginas que vas a generar.
Al compilar, Astro generará 3 archivos HTML:
/perros/labrador/index.html,/perros/pastor-aleman/index.html/perros/caniche/index.html
Pasando datos con props
El ejemplo anterior está bien, pero está un poco “cojo”. Hemos generado una página para cada raza de perro, y hemos usado el parámetro [raza] en el texto del componente.
Pero claro, deberíamos sacar más información de la raza (tamaño, peso, etc etc) para mostrarlo en nuestra web ¿Tenemos que hacer una segunda consulta?
getStaticPaths nos permite pasar datos a cada página generada mediante la propiedad props.
---
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
// 1. Obtenemos TODOS los artículos de nuestra colección
const posts = await getCollection('blog');
// 2. Devolvemos una ruta por cada artículo
return posts.map((post) => {
return {
// params: Lo que va en la URL (coincide con el nombre del archivo [slug])
params: { slug: post.slug },
// props: Los datos completos que queremos pasar al componente
props: { post },
};
});
}
// 3. Recuperamos los datos.
// 'Astro.params' nos da la URL.
// 'Astro.props' nos da el objeto completo que pasamos arriba.
const { post } = Astro.props;
const { Content } = await post.render();
---
<h1>{post.data.title}</h1>
<Content />
Este es el patrón estándar en Astro: Carga los datos en getStaticPaths y pásalos vía props.
Así evitas tener que volver a consultar la base de datos o el sistema de archivos dentro del componente.
Parámetros rest [...path]
A veces la estructura de la URL no es tan simple como /blog/titulo. A veces necesitamos capturar rutas con una profundidad variable, como:
/docs/v1/instalacion/docs/v1/componentes/botones
Para esto usamos los tres puntos dentro de los corchetes: [...slug].astro.
Esto capturará cualquier ruta que coincida con ese patrón.
---
// src/pages/docs/[...path].astro
export function getStaticPaths() {
return [
{ params: { path: 'v1/intro' } },
{ params: { path: 'v1/avanzado/configuracion' } },
{ params: { path: undefined } }, // Captura la raíz /docs
];
}
const { path } = Astro.params;
---
<p>Estás viendo la ruta: {path}</p>
Rutas dinámicas vs SSR
Es importante entender que getStaticPaths es exclusivo del modo Estático (SSG).
Si configuras tu proyecto en modo Server Side Rendering (SSR) (que veremos en el próximo módulo), getStaticPaths deja de ser necesario en la mayoría de los casos.
- En SSG: “Genera estas 100 páginas ahora y guárdalas como HTML”. (Necesita
getStaticPaths). - En SSR: “Espera a que venga un usuario, mira qué URL pide (
/producto/999), consulta la base de datos en tiempo real y genera el HTML al vuelo”. (No usagetStaticPaths).
