Rutas dinámicas en Astro: Dominá [slug].astro y getStaticPaths() como un pro
Si alguna vez trabajaste con frameworks como Next.js o Nuxt, sabés que la magia de la web moderna reside en no tener que crear un archivo .astro o .vue por cada página que querés mostrar. Imaginate que tenés un blog con 500 artículos. ¿Realmente vas a crear 500 archivos manualmente? Ni loco.
Acá es donde entran las rutas dinámicas. En este artículo, te voy a enseñar cómo usar el patrón de archivos con corchetes [slug].astro y la función fundamental getStaticPaths() para generar contenido a partir de datos, ya sea que vengan de un CMS, un archivo local o una API.
¿Qué son las rutas dinámicas?
En un sitio estático como el que podés construir con Astro, las rutas suelen ser archivos físicos en la carpeta src/pages/. Si tenés src/pages/contacto.astro, tenés la URL /contacto.
Pero, ¿qué pasa cuando la URL depende de un parámetro variable? Por ejemplo: /blog/mi-primer-post, /blog/tutorial-astro, etc. En estos casos, usamos un parámetro de ruta. Astro detecta que el nombre del archivo tiene corchetes y entiende que esa parte de la URL es una variable.
El patrón [slug].astro
El término slug es una convención técnica para referirse a la parte de la URL que identifica un recurso de forma legible (ej: como-aprender-astro en lugar de id=123).
Cuando creás un archivo llamado src/pages/blog/[slug].astro, le estás diciendo a Astro: "Cualquier cosa que venga después de /blog/ debe ser tratada como una variable llamada slug."
La pieza que falta: getStaticPaths()
Como Astro es un generador de sitios estáticos (SSG) por defecto, necesita saber en tiempo de compilación cuántas páginas debe generar. No puede esperar a que un usuario haga clic para "adivinar" qué slugs existen.
Para eso usamos getStaticPaths(). Esta función es obligatoria en cualquier archivo de ruta dinámica que use renderizado estático. Su trabajo es devolver un array de objetos, donde cada objeto representa una página que Astro debe construir.
Paso a paso: Creando un Blog Dinámico
Vamos a meter las manos en la masa. Supongamos que tenemos un array de objetos que simula nuestra base de datos de posts.
1. Definamos nuestros datos
Primero, imaginemos que tenemos este archivo de datos (o que lo traemos de una API):
// src/data/posts.js
export const posts = [
{ slug: 'introduccion-a-astro', title: 'Introducción a Astro', content: 'Astro es increíble...' },
{ slug: 'rutas-dinamicas', title: 'Dominando las Rutas', content: 'Las rutas son la base...' },
{ slug: 'voseo-en-tech', title: 'Escribir en rioplatense', content: 'Che, aprendé a usar el voseo...' }
];2. Implementación de [slug].astro
Ahora, creamos el archivo src/pages/blog/[slug].astro. Fijate bien en cómo estructuramos la función getStaticPaths y cómo accedemos a los parámetros.
---
// src/pages/blog/[slug].astro
import { posts } from '../../data/posts';
export async function getStaticPaths() {
return posts.map((post) => {
return {
params: { slug: post.slug },
props: { post },
};
});
}
const { post } = Astro.props;
const { title, content } = post;
---
<html>
<head>
<title>{title}</title>
</head>
<body>
<article>
<h1>{title}</h1>
<p>{content}</p>
<a href="/">Volver al inicio</a>
</article>
</body>
</html>Explicación de lo que hicimos:
getStaticPaths(): Recorremos el arrayposts. Para cada post, devolvemos un objeto con:params: Un objeto que contiene el nombre del parámetro que definimos en el nombre del archivo (slug). Esto le dice a Astro: "Generá la URL/blog/introduccion-a-astro".props: Pasamos el objetopostcompleto como una propiedad. Esto es clave para no tener que volver a buscar el post en el array dentro del cuerpo del componente.
Astro.props: Gracias a que pasamos el post enpropsdentro degetStaticPaths, podemos recuperarlo directamente aquí sin hacer búsquedas costosas.- Renderizado: Usamos las variables
titleycontentpara llenar el HTML.
Salida esperada
Al ejecutar npm run build, Astro generará archivos físicos en la carpeta dist/ como si los hubieras escrito a mano:
dist/blog/introduccion-a-astro/index.htmldist/blog/rutas-dinamicas/index.htmldist/blog/voseo-en-tech/index.html
Si entrás a tu-sitio.com/blog/rutas-dinamicas, verás el título "Dominando las Rutas" y su contenido correspondiente.
Ejemplo práctico con un simulador de API
Para que veas que esto funciona con datos asíncronos (lo más común en el mundo real), vamos a correr un pequeño script en Python que simule cómo procesaríamos estos datos antes de pasarlos a Astro.
def get_static_paths_simulation(api_data):
# Simulamos la lógica que haría getStaticPaths()
paths = []
for item in api_data:
paths.append({
"params": {"slug": item["slug"]},
"props": {"title": item["title"]}
})
return paths
# Datos que vendrían de una API
mock_api_response = [
{"slug": "post-1", "title": "Hola Mundo"},
{"slug": "post-2", "title": "Astro es genial"},
{"slug": "post-3", "title": "Aprendiendo voseo"}
]
result = getStatic_paths_simulation(mock_api_response)
print("--- Rutas a generar ---")
for r in result:
print(f"URL: /blog/{r['params']['slug']} | Prop: {r['props']['title']}")Salida del código:
--- Rutas a generar ---
URL: /blog/post-1 | Prop: Hola Mundo
URL: /blog/post-2 | Prop: Astro es genial
URL: /blog/post-3 | Prop: Aprendiendo voseoBuenas prácticas y errores comunes
Para que no te rompas la cabeza en producción, tené en cuenta lo siguiente:
1. El error del parámetro faltante
Si definís un archivo como [id].astro pero en getStaticPaths devolvés un objeto con params: { slug: '...' }, Astro te va a tirar un error. El nombre en la llave del objeto params debe coincidir exactamente con el nombre del archivo entre corchetes.
2. No satures el build
Si tenés un CMS con 100.000 productos, generar 100.000 páginas estáticas en cada build va a hacer que tu proceso de despliegue tarde una eternidad. En esos casos, te conviene usar SSR (Server Side Rendering) en lugar de SSG. Astro te permite cambiar de modo fácilmente.
3. Usar props es más eficiente
Muchos principiantes cometen el error de hacer esto:
---// MAL EJEMPLO
const { slug } = Astro.params;
const post = posts.find(p => p.slug === slug);
---Aunque funciona, es mejor pasar los datos mediante props desde getStaticPaths. De esa forma, la lógica de búsqueda ya fue resuelta durante la fase de construcción y el componente solo se encarga de mostrar la info.
4. Slugs limpios
Asegurate de que tus slugs no tengan caracteres especiales, espacios o tildes que puedan romper la URL. Lo ideal es usar siempre kebab-case (minúsculas y guiones).
Conclusión
Las rutas dinámicas con [slug].astro y getStaticPaths() son el corazón de cualquier sitio de contenido escalable en Astro. Te permiten separar la estructura de tu página de los datos que la alimentan.
Resumen rápido:
[slug].astrodefine un patrón de URL variable.getStaticPaths()le dice a Astro qué valores puede tomar ese parámetro.paramsdefine la URL,propspasa la data al componente.
Ahora que ya sabés cómo funciona, te propongo un desafío: intentá crear una sección de "Categorías" donde cada categoría sea una ruta dinámica que filtre los posts. ¡Dale que vos podés!
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.