Navegación entre páginas y Astro.url
Enlazar en un sitio multipágina con el elemento a nativo, la diferencia crítica entre rutas absolutas de raíz y relativas, y el objeto Astro.url como la petición hecha objeto. Cómo construir URLs sin errores con el constructor URL y generar la etiqueta canónica.
Astro genera sitios multipágina: cada ruta es un documento HTML independiente, y moverse entre ellas es lo que la web hace desde su origen —seguir un enlace y cargar una página nueva—. Por eso navegar en Astro no exige aprender una API propia, sino reencontrarse con las primitivas de siempre: el enlace, el objeto URL y la petición estándar. Dominarlas es dominar, a la vez, Astro y la plataforma sobre la que se apoya.
- Enlazar entre páginas con el elemento
<a>nativo, sin componentes especiales. - Distinguir las rutas absolutas de raíz de las relativas y elegir la forma correcta.
- Leer la petición actual con
Astro.urly sus partes:pathname,searchParams,origin. - Construir URLs absolutas sin errores con
new URLy generar la etiqueta canónica.
Enlazar es, sencillamente, un ancla
Para enlazar no necesitas ningún componente del framework ni ninguna API: un elemento <a> con su atributo href es todo.
---
// src/pages/index.astro
---
<nav>
<a href="/">Inicio</a>
<a href="/blog">Blog</a>
<a href="/about">Sobre mi</a>
</nav>
Esta sencillez es una postura, no una carencia. Los frameworks orientados a aplicación envuelven cada enlace en un componente que intercepta el clic para navegar sin recargar; Astro parte del enlace nativo y deja esa mejora como una capa opcional. Si más adelante quieres transiciones sin recarga, activas el <ClientRouter /> de las View Transitions y los mismos <a> empiezan a navegar como una SPA, sin reescribir un solo enlace. La base es estándar; la mejora, aditiva.
Si vienes de otros frameworks buscarás un <Link>. En Astro no existe ni hace falta: el enlace nativo cumple, y las View Transitions lo potencian sin sustituirlo. Reservar los componentes para lo que de verdad aporta lógica —y dejar el HTML nativo donde basta— mantiene el marcado legible y ligero.
Rutas absolutas de raíz y relativas
El valor de href admite dos formas, y confundirlas es la causa más común de enlaces rotos. Una ruta absoluta de raíz empieza por barra y se resuelve siempre desde la raíz del sitio, sin importar en qué página estés. Una ruta relativa no empieza por barra y se resuelve contra la URL actual, como una dirección tomada desde donde estás parado.
href="/blog/primero"apunta siempre a la misma URL, la escribas donde la escribas.href="primero"desde/bloglleva a/blog/primero; desde/docs, a/docs/primero.
La regla práctica para enlaces internos es preferir rutas absolutas de raíz: son estables, no dependen de la página que las contiene y sobreviven a que muevas el fichero que las incluye. Las rutas relativas brillan en casos concretos —enlazar a un hermano dentro de la misma sección— pero su fragilidad ante reorganizaciones las hace mala opción por defecto.
Un solo carácter separa dos comportamientos opuestos. href="/blog" es absoluto: siempre /blog. href="blog" es relativo: desde /docs/guia te manda a /docs/guia/blog, casi nunca lo que querías. Cuando dudes de por qué un enlace aterriza donde no debe, mira primero si empieza por barra.
Astro.url: la petición hecha objeto
Dentro de cualquier página, Astro expone Astro.url: una instancia del objeto URL estándar que describe la dirección que se está sirviendo. No es una cadena, es un objeto con las partes ya diseccionadas, lo que te ahorra parsear a mano.
---
const ruta = Astro.url.pathname; // '/blog/primero'
const origen = Astro.url.origin; // 'https://midominio.com'
const query = Astro.url.searchParams; // acceso a los parametros
const esBlog = ruta.startsWith('/blog');
---
<body data-activo={esBlog}>
Con Astro.url.pathname marcas el enlace activo de un menú comparando rutas; con searchParams lees parámetros de consulta; con origin compones direcciones absolutas. Junto a él viven Astro.site —la URL canónica que declaraste en la configuración— y Astro.request, el objeto Request completo si necesitas cabeceras o método.
El uso más frecuente de pathname es marcar en qué sección está el visitante. Un componente de navegación compara la ruta actual con la de cada enlace y señala el que coincide, idealmente con aria-current para que también lo anuncien los lectores de pantalla.
---
// src/components/Nav.astro
const rutas = [
{ href: '/', texto: 'Inicio' },
{ href: '/blog', texto: 'Blog' },
];
const actual = Astro.url.pathname;
---
<nav>
{rutas.map((r) => (
<a href={r.href} aria-current={actual === r.href ? 'page' : undefined}>
{r.texto}
</a>
))}
</nav>
Fíjate en que la comparación es contra pathname, no contra la URL entera: así ignoras la query y el origen, que no deberían decidir si un enlace está activo. Cuando la lógica se complica —resaltar la sección aunque estés en una subruta— basta con cambiar la igualdad estricta por un actual.startsWith(r.href), y sigues trabajando con una simple cadena.
En un sitio estático, Astro.url se resuelve en el build: es la URL que Astro está generando para ese fichero, con pathname conocido, pero sin datos de una petición real. En renderizado bajo demanda, Astro.url refleja la petición concreta de cada visitante, incluida su query real. Misma API, dos momentos: piénsalo antes de depender de searchParams en una página estática, donde no hay usuario que los aporte.
Construir URLs sin cometer errores
Concatenar cadenas para formar URLs —pegar prefijos y rutas a mano— es una fuente clásica de barras dobles y segmentos perdidos. El objeto URL resuelve esto: su constructor toma una ruta y una base, y aplica las mismas reglas que el navegador. Astro lo aprovecha para tareas tan comunes como la etiqueta canónica.
---
// URL absoluta y canonica de la pagina actual
const canonica = new URL(Astro.url.pathname, Astro.site);
---
<link rel="canonical" href={canonica.href} />
new URL(ruta, base) combina ambas sin que tengas que preocuparte de si sobran o faltan barras, y respeta el subdirectorio del sitio si lo incluyes en la base. Es también la forma correcta de generar enlaces a recursos —imágenes de redes sociales, feeds— cuya URL debe ser absoluta. Delegar en el objeto URL en vez de manipular cadenas elimina de raíz toda una familia de bugs.
La distinción entre enlace interno y absoluto no es capricho, sino contexto. Dentro de tu sitio, una ruta absoluta de raíz basta y es más corta. Pero en cuanto la dirección sale del documento —una etiqueta og:image que lee un servidor de redes sociales, un enlace dentro de un feed RSS que abrirá otro lector, un correo— necesita ser absoluta, con dominio incluido, porque quien la consume no conoce tu origen. La regla se resume así: relativo o de raíz para navegar dentro; absoluto con Astro.site para todo lo que cruza la frontera de tu sitio.
Pregúntate siempre quién va a leer la URL. Si la resuelve el propio navegador del visitante mientras está en tu sitio, una ruta de raíz vale. Si la va a leer otro sistema —un buscador, un cliente de correo, una red social, un agregador— tiene que ser absoluta, porque ese sistema no tiene tu origen como referencia. new URL(ruta, Astro.site) es tu herramienta para esos casos.
flowchart LR R[Astro.url] --> P[pathname] R --> Q[searchParams] R --> O[origin] S[Astro.site] --> C[new URL ruta y site] P --> C C --> CAN[URL canonica absoluta] style R fill:#89b4fa,color:#11111b style S fill:#89b4fa,color:#11111b style CAN fill:#a6e3a1,color:#11111b
La forma en que Astro te hace navegar encierra su tesis más discreta y más radical: la mejor manera de construir para la web suele ser usar la web. Donde otros frameworks reemplazan el enlace por un componente, la URL por un objeto propio y la navegación por un router de cliente, Astro se apoya en las primitivas que el navegador ya trae —el <a>, el objeto URL, la petición y la respuesta estándar— y solo añade encima cuando el estándar se queda corto. Esta postura tiene un nombre viejo y valioso: mejora progresiva. Empiezas con algo que funciona sin JavaScript —enlaces que cargan páginas— y añades sofisticación como una capa que se puede quitar sin romper lo esencial. Activar las View Transitions no reescribe tus enlaces; los reinterpreta. El beneficio profundo no es solo robustez, aunque un sitio que navega sin depender de un runtime de cliente es más resistente por definición. Es también economía conceptual: cada primitiva que reutilizas de la plataforma es una que no tienes que aprender, versionar ni depurar dos veces. Dominar Astro.url es dominar URL; saber enlazar en Astro es saber enlazar en HTML. Un framework que te devuelve a los fundamentos en lugar de alejarte de ellos no te ata a sí mismo: te enseña la web, que es lo único que no va a deprecarse.
- Crea un menú con enlaces absolutos de raíz a tres páginas y comprueba que funcionan desde cualquier ruta.
- Añade un enlace relativo desde una página anidada y observa cómo su destino depende de la URL actual.
- Usa
Astro.url.pathnamepara marcar como activo el enlace de la sección en la que estás. - Genera la etiqueta canónica con
new URL(Astro.url.pathname, Astro.site)y verifica que produce una URL absoluta correcta.