Rutas estáticas y dinámicas en Astro

Resumen

Trabajar con rutas estáticas y dinámicas en Astro es lo que te permite mostrar una colección de artículos y, al mismo tiempo, acceder al detalle de cada uno desde un archivo Markdown. Aquí ves cómo estructurar la carpeta content, usar getCollection y preparar los slugs para una ruta dinámica.

¿Cómo se organizan las rutas estáticas en Astro?

Las rutas en Astro viven dentro de la carpeta pages y se definen por el nombre del archivo, sin importar la extensión. Puedes usar .astro, .md, .mdx, .js o .tsx para crear cada ruta.

Las rutas estáticas son las que tú nombras manualmente: un 404, un about, un contact o el index principal. También puedes crear rutas basadas en carpetas, como un folder llamado post con su propio index.astro adentro [02:00].

¿Qué es una ruta estática en Astro? Es una ruta cuyo nombre defines tú a través del archivo o carpeta dentro de pages. Por ejemplo, pages/post/index.astro genera la URL /post.

¿Cómo traer contenido con getCollection?

En lugar de leer archivos manualmente, Astro ofrece getCollection, un método de astro:content que lee una carpeta dentro de content y te devuelve toda la colección lista para iterar.

El flujo es directo:

  • Importas la función con import { getCollection } from 'astro:content'.
  • Creas una constante con const post = await getCollection('tips').
  • Pasas como argumento el nombre de la subcarpeta dentro de content, no una ruta completa [04:30].

Esto cambia respecto al método anterior, donde se accedía con una ruta tipo ../../. Ahora basta con nombrar la colección. Puedes tener varias colecciones en paralelo: tips, autores u otros recursos, y cada una se consulta de la misma forma.

Esta propuesta es parte del enfoque de Astro de centrarse en el contenido sin depender de un API externo, un headless CMS ni frameworks más pesados.

¿Cómo ordenar los posts por fecha con sort?

Una vez tienes la colección, lo natural es ordenarla. En este caso, por la fecha de publicación. Aquí entra el método sort de JavaScript [06:10].

La lógica compara dos elementos A y B, accediendo a A.data.pubDate y B.data.pubDate. Como pubDate es un objeto fecha, usas valueOf() para convertirlo a un valor numérico comparable:

js const post = (await getCollection('tips')).sort( (a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf() );

Si te interesa profundizar en estos métodos de arrays, el curso de JavaScript en Platzi cubre sort, map y otras funciones esenciales.

¿Qué hago cuando el editor marca errores?

Los errores son tus amigos. Visual Studio Code y la interfaz visual de Astro te avisan cuando hay un cierre de paréntesis sobrante, un await mal envuelto o una ruta inexistente. Lee el mensaje, ubica la línea y corrige antes de seguir.

¿Qué información entrega getCollection en cada item?

Un console.log(post) te muestra la estructura real que recibes, y vale la pena revisarla antes de iterar [09:45]. Cada elemento incluye:

  • id: el nombre del archivo dentro de la ruta de la colección.
  • slug: una versión amigable del nombre, sin extensión ni caracteres raros, lista para usar en URLs.
  • body: el contenido del Markdown como texto.
  • collection: a qué colección pertenece, por ejemplo tips.
  • data: los metadatos del frontmatter (title, pubDate, tags).
  • render: una función que renderiza el contenido del Markdown en tu página.

¿Qué es el slug en una colección de Astro? Es la versión limpia del nombre del archivo Markdown, sin extensión ni caracteres especiales. Lo usas para construir URLs dinámicas tipo /post/mi-articulo.

¿Cómo preparar el componente Card para rutas dinámicas?

El componente Card debe recibir el slug como prop adicional, de tipo string. Lo declaras en la interfaz de props y lo destructuras junto al resto de valores [11:30].

El href del card pasa de ser estático a componerse de forma dinámica. La ruta padre es post y el hijo es el slug recibido:

astro <a href={/post/${slug}}>...</a>

Dentro del index.astro de post, cada item se mapea con sus datos:

  • title desde post.data.title.
  • pubDate desde post.data.pubDate.
  • tags desde post.data.tags.
  • slug desde post.slug.

¿Por qué mi ruta de detalle muestra una página vacía?

Porque la ruta dinámica todavía no existe. La estructura /post/[slug] se compone correctamente en el href, pero hace falta crear el archivo que renderice el detalle de cada artículo individual a partir del slug recibido.

Ese paso es justo el que sigue: construir la ruta dinámica que lea el Markdown correspondiente y muestre el contenido completo. ¿Qué nombre le pondrías tú a ese archivo dinámico dentro de pages/post? Cuéntame en los comentarios.