File‑based routing en Astro: cómo funciona pages/index.astro y pages/about.astro
Introducción
Cuando arrancás un nuevo proyecto con Astro, una de las primeras cosas que notás es la carpeta pages/. Ahí dentro, cada archivo .astro se convierte automáticamente en una ruta accesible del sitio. Este mecanismo se llama file‑based routing y es la forma más directa de crear páginas sin tener que definir manualmente un router o configurar rutas en un archivo separado.
En este artículo vas a aprender:
- Qué es el file‑based routing y por qué es útil.
- Cómo Astro interpreta los archivos dentro de
pages/. - Qué contiene un archivo típico como
pages/index.astroypages/about.astro. - Cómo crear enlaces entre páginas, usar rutas dinámicas y manejar errores 404.
- Buenas prácticas y errores comunes que suelen aparecer al trabajar con este enfoque.
El tutorial está pensado para desarrolladores que ya conocen los conceptos básicos de HTML, CSS y JavaScript (o TypeScript) y que quieren empezar a usar Astro para generar sitios estáticos o híbridos con renderizado en el servidor o en el cliente.
¿Qué es el file‑based routing?
El file‑based routing (enrutamiento basado en archivos) es una convención donde la estructura del sistema de archivos define directamente las rutas URL de una aplicación. En lugar de escribir código que diga "si la URL es /about entonces renderizar tal componente", simplemente creás un archivo llamado about.astro dentro de la carpeta pages/ y Astro se encarga del resto.
Esta aproximación tiene varias ventajas:
- Claridad: al mirar la carpeta
pages/ves de un vistazo todas las rutas disponibles. - Menos boilerplate: no necesitás importar ni registrar rutas manualmente.
- Escalabilidad: a medida que el proyecto crece, basta con agregar nuevos archivos para nuevas páginas.
Astro sigue esta filosofía y la combina con su modelo de componentes, permitiéndote mezclar HTML, JavaScript y datos de forma muy fluida.
Cómo lo implementa Astro
Cuando ejecutás astro dev o astro build, Astro hace lo siguiente:
- Recorre recursivamente la carpeta
src/pages/(opages/si no usassrc/). - Por cada archivo con extensión
.astro,.mdo.mdxcrea una ruta cuya ruta de archivo se traduce a la ruta URL. - El archivo
index.astrodentro de una carpeta se convierte en la ruta raíz de esa carpeta (por ejemplo,pages/blog/index.astro→/blog/). - Los archivos cuyo nombre empieza con corchetes, como
[slug].astro, se tratan como parámetros dinámicos. - Los archivos con tres puntos, como
[...slug].astro, son catch‑all y coinciden con cualquier ruta que no haya sido capturada previamente.
Este proceso ocurre en tiempo de desarrollo y también en el build, de modo que el resultado final es un conjunto de archivos HTML estáticos (o bien, si usás modo híbrido, los archivos necesarios para hidratación en el cliente).
Estructura básica del proyecto Astro
Un proyecto típico creado con npm create astro@latest tiene aproximadamente esta forma:
mi-proyecto-astro/
├─ public/
├─ src/
│ ├─ components/
│ ├─ layouts/
│ └─ pages/
│ ├─ index.astro
│ ├─ about.astro
│ └─ blog/
│ ├─ index.astro
│ └─ [slug].astro
└─ astro.config.mjsLa carpeta src/ es opcional; podés colocar pages/ directamente en la raíz si preferís. Lo importante es que Astro siempre busca dentro de pages/ (o src/pages/).
pages/index.astro: la página de inicio
El archivo pages/index.astro representa la ruta raíz del sitio (/). Un ejemplo sencillo podría ser:
---
// Este es el bloque de componente (frontmatter).
// Aquí podés importar componentes, definir props, leer datos, etc.
import Layout from '../layouts/Layout.astro'
import { title } from '../data/siteData.js'
---
<Layout pageTitle={title}>
<h1>Bienvenido a mi sitio hecho con Astro</h1>
<p>Esta es la página de inicio. Desde acá podés navegar a otras secciones usando los enlaces de abajo.</p>
<nav>
<ul>
<li><a href='/about/'>Sobre nosotros</a></li>
<li><a href='/blog/'>Blog</a></li>
</ul>
</nav>
</Layout>Salida esperada
Al visitar http://localhost:4321/ (el puerto por defecto de astro dev) verás algo como:
<!DOCTYPE html>
<html lang='es'>
<head>
<meta charset='utf-8'>
<title>Mi Sitio Astro</title>
<!-- otros meta tags generados por Layout -->
</head>
<body>
<header>
<!-- contenido del Layout -->
</header>
<main>
<h1>Bienvenido a mi sitio hecho con Astro</h1>
<p>Esta es la página de inicio. Desde acá podés navegar a otras secciones usando los enlaces de abajo.</p>
<nav>
<ul>
<li><a href='/about/'>Sobre nosotros</a></li>
<li><a href='/blog/'>Blog</a></li>
</ul>
</nav>
</main>
<footer>
<!-- contenido del Layout -->
</footer>
</body>
</html>Observá que el contenido del componente Layout se inserta alrededor del contenido principal, gracias al slot <slot /> que suele haber dentro del layout.
pages/about.astro: una página estática simple
La página about.astro sigue el mismo patrón. Un ejemplo típico podría ser:
---
import Layout from '../layouts/Layout.astro'
---
<Layout pageTitle='Sobre nosotros'>
<h1>Sobre nosotros</h1>
<p>Somos un equipo apasionado por la web moderna y nos encanta construir sitios rápidos y accesibles con Astro.</p>
<section>
<h2>Nuestro enfoque</h2>
<ul>
<li>Renderizado estático por defecto.</li>
<li>Hidratación selectiva de componentes interactivos.</li>
<li>Integración sencilla con Markdown y MDX.</li>
</ul>
</section>
</Layout>Salida esperada
Al ir a http://localhost:4321/about/ obtendrás:
<!DOCTYPE html>
<html lang='es'>
<head>
<meta charset='utf-8'>
<title>Sobre nosotros</title>
</head>
<body>
<header>…</header>
<main>
<h1>Sobre nosotros</h1>
<p>Somos un equipo apasionado por la web moderna y nos encanta construir sitios rápidos y accesibles con Astro.</p>
<section>
<h2>Nuestro enfoque</h2>
<ul>
<li>Renderizado estático por defecto.</li>
<li>Hidratación selectiva de componentes interactivos.</li>
<li>Integración sencilla con Markdown y MDX.</li>
</ul>
</section>
</main>
<footer>…</footer>
</body>
</html>Notá que la única diferencia con respecto al index es el contenido dentro del <main> y el título de la página.
Enlaces entre páginas
Para moverte entre las rutas que definís con archivos, podés usar etiquetas <a> normales, tal como se vio en los ejemplos anteriores. Astro también provee un componente <Link> que hace prefetching automático cuando el usuario se acerca al enlace (solo en modo de desarrollo o cuando se usa el adaptor adecuado).
Ejemplo usando <Link>:
---
import { Link } from 'astro/components'
---
<nav>
<ul>
<li><Link href='/about/'>Sobre nosotros</Link></li>
<li><Link href='/blog/'>Blog</Link></li>
</ul>
</nav><Link> renderiza un <a> detrás de escena, pero agrega atributos como data-prefetch que el cliente de Astro interpreta para cargar el código de la página destino antes de que el usuario haga click, mejorando la percepción de velocidad.
Rutas dinámicas: [slug].astro
Supongamos que tenés un blog y querés que cada artículo tenga su propia URL basada en su slug (por ejemplo, /blog/mi-primer-post/). Para eso creás un archivo entre corchetes dentro de la carpeta correspondiente:
src/pages/blog/[slug].astroEl contenido de ese archivo podría ser:
---
import Layout from '../../layouts/Layout.astro'
import { getPostBySlug } from '../../lib/posts.js'
// Astro.params contiene los valores de los corchetes
const { slug } = Astro.params
// Si no encontramos el post, devolvemos un 404
const post = getPostBySlug(slug)
if (!post) {
return Astro.redirect('/404/')
}
---
<Layout pageTitle={post.title}>
<article>
<h1>{post.title}</h1>
<time datetime={post.date}>{post.date.toLocaleDateString()}</time>
<div set:html={post.content} />
</article>
</Layout>Salida esperada
Si tenés un post con slug mi-primer-post y título Mi primer post, al visitar /blog/mi-primer-post/ verás algo como:
<!DOCTYPE html>
<html lang='es'>
<head>
<meta charset='utf-8'>
<title>Mi primer post</title>
</head>
<body>
<header>…</header>
<main>
<article>
<h1>Mi primer post</h1>
<time datetime='2025-09-25'>25 de sep. de 2025</time>
<div>
<p>Este es el contenido del post en HTML…</p>
</div>
</article>
</main>
<footer>…</footer>
</body>
</html>Parámetros de ruta y uso de Astro.params
Los corchetes no solo aceptan un segmento; podés tener varios, como [category]/[slug].astro. En ese caso Astro.params será un objeto con ambas propiedades:
---
const { category, slug } = Astro.params
---Podés también definir parámetros opcionales agregando un signo de interrogación dentro del corchete, aunque Astro no lo soporta de forma nativa; para eso se suele usar un catch‑all y luego validar manualmente.
Catch‑all routes: [...all].astro
Cuando querés que una misma página maneje múltiples niveles de ruta (por ejemplo, un wiki donde /docs/intro/, /docs/intro/instalacion y /docs/intro/instalacion/paso-a-paso todos muestren el mismo layout pero con contenido diferente según la profundidad), usás la sintaxis de tres puntos:
src/pages/docs/[...slug].astroDentro del componente podés leer Astro.params.slug, que será un arreglo de los segmentos capturados:
---
import Layout from '../../layouts/Layout.astro'
---
const segments = Astro.params.slug ?? []
---
<Layout pageTitle='Documentación'>
<h1>Documentación</h1>
{segments.length === 0 ? (
<p>Seleccioná un tema de la barra lateral.</p>
) : (
<div>
<h2>{segments.join(' > ')}</h2>
<p>Contenido correspondiente a la ruta {@segments.join('/')}</p>
</div>
)}
</Layout>Así, visitar /docs/ mostrará el mensaje de selección, mientras que /docs/git/commits/ mostrará "git > commits" como título.
Manejo de 404 personalizado
Astro brinda una página de error 404 por defecto, pero podés sobrescribirla creando un archivo pages/404.astro. Este archivo se muestra siempre que ninguna ruta coincida con la URL solicitada.
Ejemplo simple:
---
import Layout from '../layouts/Layout.astro'
---
<Layout pageTitle='Página no encontrada'>
<h1>404 – Página no encontrada</h1>
<p>Lo sentimos, la página que buscás no existe.</p>
<p><a href='/'>Volver al inicio</a></p>
</Layout>Al visitar una ruta inexistente como /foo/bar/ verás exactamente ese contenido.
Buenas prácticas al usar file‑based routing
- Mantené la carpeta
pages/ordenada: agrupar rutas relacionadas en subcarpetas evita que la lista se vuelva caótica. - Usá componentes de layout reutilizables: así evitás repetir el
<head>, header y footer en cada página. - Prefetíche enlaces con
<Link>cuando la navegación sea frecuente; esto mejora la percepción de velocidad sin mucho esfuerzo. - Aprovechá el prerenderizado por defecto: si tu página no necesita datos del cliente, dejá que Astro la genere como HTML estático en tiempo de build.
- Documentá las rutas dinámicas: agregá un comentario al inicio del archivo indicando qué parámetros espera y de qué tipo son (string, número, etc.).
- Validá los parámetros: en rutas como
[id].astroverificá que el valor sea válido antes de usarlo para evitar errores en tiempo de renderizado. - Evité rutas que sobrescriban otras accidentalmente: por ejemplo, tener tanto
pages/blog/index.astrocomopages/blog/[slug].astropuede hacer que/blog/nunca coincida con el índice si el parámetro puede ser cadena vacía; asegurá que los patrones no se solapen.
Errores comunes y cómo evitarlos
- Olvidar exportar el componente: en Astro cada archivo
.astroes un componente por sí mismo; no necesitásexport default, pero si mezclas con archivos.jso.tsasegurá de exportar correctamente. - Usar rutas absolutas en
<a href>: si usás/blog/está bien, pero si usásblog/sin la barra inicial el enlace será relativo a la página actual y puede romperse en subrutas. - Confundir
pages/consrc/pages/: si tu proyecto tienesrc/y buscás en la raíz, Astro no encontrará tus páginas. Verificá la configuración enastro.config.mjs(la opciónsrcDir). - No manejar el caso de parámetro vacío: en una ruta dinámica como
[page].astro, si alguien visita/y tenés también unindex.astro, el servidor podría intentar coincidir con la dinámica y fallar. La solución es asegurarse de que la ruta estática tenga prioridad (lo que ocurre naturalmente si el archivo estático existe). - Olvidar volver a ejecutar
astro devdespués de agregar un nuevo archivo: aunque Astro recarga en caliente, a veces es necesario reiniciar el proceso si cambias la estructura de carpetas de forma drástica.
Integración con Markdown y MDX
Astro trata los archivos .md y .mdx dentro de pages/ como rutas también. Esto significa que podés crear una página simplemente escribiendo Markdown:
---
title: 'Guía de introducción'
---
# Guía de introducción
Este es el contenido en Markdown.
- Punto uno
- Punto dos
```js
console.log('Hola desde un bloque de código');
Al visitar la ruta correspondiente (por ejemplo, `/guia-de-introduccion/`) obtendrás una página HTML con el Markdown convertido, el frontmatter disponible como propiedades y la posibilidad de incluir componentes de Astro directamente dentro del MDX.
---
## Optimización y prerenderizado
Por defecto, Astro prerenderiza todas las páginas en tiempo de build, generando archivos HTML estáticos que se sirven rápidamente desde un CDN o desde `public/`. Si necesitás datos que cambian frecuentemente (por ejemplo, el usuario actual o el estado de un carrito), podés cambiar el modo de renderizado de una página específica usando el export `export const prerender = false;` o `export const prerender = true;` según corresponda.
Ejemplo de modo híbrido:
```astro
---
export const prerender = false;
// Esta página se renderizará en el servidor en cada request
---
<Layout>
<h1>Hora del servidor</h1>
<p>{new Date().toLocaleTimeString()}</p>
</Layout>Así podés combinar lo mejor de ambos worlds: páginas estáticas para contenido que no cambia y renderizado en el servidor para lo dinámico.
Conclusión
El file‑based routing de Astro es una de las características que hace que el framework sea tan productivo y agradable de usar. Al simplemente colocar archivos en la carpeta pages/ obtenés rutas inmediatamente disponibles, sin escribir configuraciones de router ni preocuparte por la sincronización entre URL y componentes.
En este artículo vimos cómo crear la página de inicio y una página estática con pages/index.astro y pages/about.astro, cómo usar enlaces normales y el componente <Link>, cómo trabajar con rutas dinámicas y catch‑all, cómo manejar errores 404 y cuáles son las buenas prácticas y los errores más típicos.
Con esta base podés empezar a construir sitios más complejos: blogs, documentación, tiendas o cualquier aplicación que se beneficie de la generación estática y la posibilidad de renderizado selectivo en el cliente. La próxima etapa podría ser explorar el uso de endpoints (src/pages/api/*.ts) para crear rutas de API o adentrarse en los modos de renderizado híbrido y de servidor completo (SSR) que Astro también soporta.
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.