trailingSlash, base y la configuración de rutas
Las claves de astro.config que gobiernan la forma de las URLs: trailingSlash como política de la barra final, base para desplegar en un subdirectorio, build.format para la forma física de los ficheros y site como referencia canónica de las direcciones absolutas.
El enrutado por ficheros dibuja un árbol de URLs limpio, pero ese árbol tiene que aterrizar en un mundo desordenado de hosts, subdirectorios y reglas de canonicidad. Cuatro claves de astro.config.mjs son las costuras donde lo ideal se ajusta a lo real: trailingSlash fija la barra final, base declara el subdirectorio, build.format decide la forma física del fichero y site da la referencia absoluta. Configurarlas bien es la diferencia entre un despliegue sin sorpresas y una tarde persiguiendo enlaces rotos.
- Fijar una política coherente de barra final con
trailingSlash. - Desplegar un sitio bajo un subdirectorio con
basesin romper los enlaces. - Entender cómo
build.formatdetermina la forma física de los ficheros generados. - Declarar la URL canónica con
sitey saber qué depende de ella.
trailingSlash: la política de la barra final
Una decisión aparentemente trivial genera sorprendentes dolores de cabeza: ¿/blog o /blog/? Para un servidor, las dos direcciones son potencialmente distintas, y tratarlas con descuido reparte tu contenido entre dos URLs, diluye el SEO y rompe cachés. La clave trailingSlash fija una política única y coherente.
import { defineConfig } from 'astro/config';
export default defineConfig({
trailingSlash: 'never',
});
Admite tres valores, y cada uno expresa una postura:
never
Las URLs no llevan barra final. /blog/ se considera incorrecta y no casa con la ruta. Direcciones limpias y una sola forma válida.
always
Toda URL termina en barra. /blog se trata como no válida frente a /blog/. Coherente con la salida en carpetas.
ignore
El valor por defecto. Astro acepta ambas formas sin forzar ninguna. Cómodo al empezar, ambiguo a escala.
En desarrollo, esta política se nota de inmediato: con never, visitar /blog/ devuelve un 404; con always, quien lo hace es /blog. La recomendación para un proyecto que se toma en serio su canonicidad es elegir explícitamente always o never —cuál importa menos que la consistencia— y enlazar siempre en esa forma. Dejarlo en ignore pospone una decisión que tu host y tu SEO acabarán tomando por ti, peor.
trailingSlash fija la política dentro de Astro, pero el alojamiento donde despliegas tiene la suya, y ambas deben coincidir. Muchos CDNs y hosts estáticos redirigen por su cuenta entre la forma con y sin barra; si su regla contradice la tuya, aparecen redirecciones dobles o incluso bucles. Antes de dar por cerrada la decisión, comprueba qué hace tu proveedor y alinéalo con el valor que elegiste aquí.
base: vivir en un subdirectorio
Por defecto Astro asume que tu sitio cuelga de la raíz del dominio. Pero a veces no es así: publicas la documentación en midominio.com/docs, o despliegas en un alojamiento que te sirve bajo el nombre del repositorio. La clave base declara ese prefijo, y a partir de ahí todas tus rutas viven bajo él.
export default defineConfig({
site: 'https://midominio.com',
base: '/docs',
});
Con base: '/docs', el fichero src/pages/index.astro ya no sirve / sino /docs, y src/pages/guia.astro pasa a /docs/guia. El punto delicado —y la fuente de casi todos los errores con base— es que Astro no reescribe automáticamente tus enlaces. Un <a href="/guia"> escrito a mano seguirá apuntando a /guia, fuera del subdirectorio, y se romperá. Debes incluir el prefijo tú.
Para no codificarlo a mano, Astro expone el valor en import.meta.env.BASE_URL, que refleja lo que pusiste en base. Construir los enlaces a partir de esa variable los hace inmunes a que cambies el prefijo mañana.
---
const base = import.meta.env.BASE_URL; // '/docs'
---
<a href={`${base}/guia`}>Guia</a>
La misma cautela vale para los recursos, no solo para los enlaces. La ruta de una imagen en public, la de una hoja de estilos que referencias con URL absoluta o la de un script deben incluir el base, o apuntarán fuera del subdirectorio. Los assets que resuelve Vite —una imagen importada desde src— ya lo tienen en cuenta por ti; las rutas que escribes a mano, no. Por eso conviene concentrar la construcción de rutas en un puñado de helpers que lean BASE_URL una sola vez, en lugar de repartir el prefijo por todo el proyecto.
El malentendido recurrente: creer que fijar base reescribe los enlaces del sitio. No lo hace. base cambia dónde se generan las rutas, pero tus href absolutos siguen siendo literales. Compón los enlaces internos con import.meta.env.BASE_URL y evitarás que todo el sitio se rompa al desplegarlo en un subdirectorio.
build.format: cómo se escriben los ficheros
Cuando Astro construye un sitio estático, debe decidir con qué forma física escribe cada página en el disco, y esa forma condiciona la URL final. La clave build.format gobierna esa decisión.
directory—el valor por defecto— escribe cada página comoruta/index.html. Así/blogse sirve desdeblog/index.html, una forma que encaja con URLs terminadas en barra.fileescribe cada página comoruta.html./blogsale deblog.html, más afín a URLs sin barra final.preserverespeta la estructura exacta de tus ficheros fuente, sin reorganizarla hacia ninguno de los dos moldes.
Que directory sea el valor por defecto no es casual. Escribir cada página como index.html dentro de su propia carpeta produce URLs que funcionan igual con o sin barra final en la mayoría de servidores, un comportamiento seguro que no exige configurar nada. file genera menos ficheros y direcciones más planas, a cambio de depender más de cómo tu host resuelve las extensiones. Elegir entre uno y otro es, en el fondo, decidir cuánto delegas en el alojamiento y cuánto controlas tú desde el build.
build.format y trailingSlash no son independientes: juntos determinan la forma canónica de tus URLs y cómo las resuelve el host. trailingSlash: 'never' conviene con format: 'file'; always casa con directory. Elegir combinaciones coherentes evita redirecciones sorpresa que algunos alojamientos aplican por su cuenta.
flowchart TD CFG[astro config] --> TS[trailingSlash] CFG --> B[base] CFG --> BF[build format] CFG --> ST[site] TS --> POL[politica de barra final] B --> SUB[prefijo de subdirectorio] BF --> FIS[forma fisica del fichero] ST --> ABS[URLs absolutas y canonicas] POL --> URL[forma final de las URLs] SUB --> URL FIS --> URL style CFG fill:#89b4fa,color:#11111b style URL fill:#a6e3a1,color:#11111b
site: la referencia para lo absoluto
La última pieza no cambia el enrutado interno, pero es la que da sentido a las URLs absolutas. site declara la URL canónica de producción —https://midominio.com— y es la base sobre la que Astro y sus integraciones construyen direcciones completas: el sitemap, las etiquetas canónicas, las URLs de un feed RSS, las metaetiquetas de redes sociales.
Sin site, Astro.site es undefined y cualquier new URL(ruta, Astro.site) falla; con él, tienes una fuente única de verdad para el dominio. Junto con base, forman el par que responde a las dos preguntas de ubicación de todo despliegue: en qué dominio vives —site— y bajo qué subruta dentro de él —base—.
Es fácil confundirlos porque ambos hablan de dónde vive el sitio, pero operan en planos separados. site es el dominio absoluto —el https://midominio.com— y solo importa para construir URLs completas de cara al exterior: sitemap, canónicas, feeds. base es el prefijo interno bajo ese dominio y afecta a cómo se generan y enlazan las rutas del propio sitio. Puedes tener uno sin el otro: un sitio en la raíz de su dominio declara site pero no necesita base. Tenerlos claros por separado evita el error de tocar uno esperando el efecto del otro.
Vistas juntas, las cuatro claves componen la dirección final de tu sitio por capas. Un fichero de configuración que las declare todas se lee casi como una plantilla de URL.
// astro.config.mjs — las cuatro claves colaborando
export default defineConfig({
site: 'https://midominio.com',
base: '/docs',
trailingSlash: 'never',
build: { format: 'file' },
});
Con esta combinación, una página en src/pages/guia.astro se sirve en https://midominio.com/docs/guia, sin barra final y generada como guia.html. Cada clave ha aportado su tramo: site el dominio, base el subdirectorio, trailingSlash la ausencia de barra y build.format la forma del fichero. Leer la URL final de izquierda a derecha es, en el fondo, recorrer la configuración entera.
Las cuatro claves de esta lección comparten una misión que rara vez se nombra: reconciliar el árbol de rutas ideal que dibujaste en src/pages con el mundo concreto y desordenado donde ese árbol tiene que aterrizar. El enrutado por ficheros es una abstracción limpia —fichero igual a URL— pero el despliegue real está lleno de asperezas que la abstracción ignora: un host que exige barra final y otro que la prohíbe, un dominio que te da solo un subdirectorio, un alojamiento que reescribe direcciones a su antojo. trailingSlash, base, build.format y site son las costuras donde lo ideal se ajusta a lo real. Y su diseño enseña algo sobre buenas configuraciones: cada una aísla una variabilidad del entorno tras un único punto de control. La barra final vive en un sitio, el subdirectorio en otro, la forma física del fichero en un tercero, el dominio en un cuarto. Ninguna se filtra por tu código en forma de literales repartidos; todas se declaran una vez y se derivan a partir de ahí —de ahí que exista import.meta.env.BASE_URL—. Esta es la diferencia entre una configuración que te salva y una que te ata: la buena no esconde el entorno, lo parametriza, de modo que cambiar de host o mudarte a un subdominio sea editar una línea y no perseguir cientos de enlaces. La abstracción te da el mapa; la configuración lo pega, sin arrugas, sobre el terreno.
- Fija
trailingSlash: 'never'y comprueba endevque visitar una URL con barra final devuelve 404. - Añade
base: '/docs'y observa cómo cambian las rutas; corrige un enlace roto usandoimport.meta.env.BASE_URL. - Alterna
build.formatentredirectoryyfile, construye y examina cómo cambian los ficheros generados endist. - Declara
sitey genera una URL absoluta connew URL; razona qué integraciones dependen de esa clave.