Páginas 404 y 500 y redirecciones
Los bordes del enrutado: una página 404 personalizada para las rutas que no existen, una página 500 para los errores de servidor bajo demanda, y la clave redirects para mudar URLs sin escribir código. Cómo se materializan las redirecciones en modo estático y bajo demanda.
Cualquier framework acierta cuando la ruta existe y todo va bien; la calidad de un sistema de rutas se mide en los bordes: qué ocurre cuando la dirección no existe, cuando el render falla, cuando la URL de ayer ya no es la de hoy. Astro trata esos bordes como rutas de primera clase —un 404 y un 500 son páginas normales, una redirección es una entrada declarativa— para que la experiencia del error y del cambio no quede en manos del azar.
- Crear una página
404personalizada para las rutas que no casan con ninguna. - Entender el papel de la página
500y por qué solo actúa en renderizado bajo demanda. - Declarar redirecciones desde la configuración con la clave
redirects. - Distinguir cómo se materializa una redirección en modo estático frente a bajo demanda.
La página 404: cuando no hay ruta que valga
Por muy completo que sea tu mapa de rutas, siempre habrá quien pida una URL que no existe: un enlace roto, una dirección mal tecleada, un contenido que retiraste. Astro te deja controlar esa experiencia con una convención mínima: un fichero src/pages/404.astro. Cuando ninguna ruta casa con la petición, Astro sirve esa página en lugar de un error genérico.
---
// src/pages/404.astro
---
<html lang="es">
<head><title>Pagina no encontrada</title></head>
<body>
<h1>404</h1>
<p>Esta pagina no existe. Vuelve al <a href="/">inicio</a>.</p>
</body>
</html>
Es una página normal en todo lo demás: puede usar tu layout, tus estilos y hasta islas interactivas —un buscador que ayude a reorientar al visitante—. También puede escribirse en .md o .mdx si lo prefieres. En un sitio estático, este fichero se compila a 404.html, y la mayoría de alojamientos lo sirven automáticamente ante cualquier ruta desconocida; en dev, Astro te lo muestra para que lo veas tal como saldrá.
Un matiz de estados conviene conocerlo. En renderizado bajo demanda, Astro sirve la página 404 con el código HTTP 404 correcto, como debe ser: buscadores y clientes entienden que la ruta no existe. En un sitio puramente estático no hay servidor que fije ese código en el momento, así que depende de tu alojamiento servir 404.html con el estado adecuado. Casi todos lo hacen, pero es una de esas cosas que merece una comprobación real antes de fiarte.
La página 500: el fallo del servidor
Su hermana es src/pages/500.astro, y atiende un caso distinto: no la ausencia de una ruta, sino un error no capturado mientras se renderiza una página. A diferencia del 404, la 500 solo tiene sentido en renderizado bajo demanda: un sitio estático se genera en el build, así que si algo falla, falla ahí y nunca llega a un usuario. Solo un servidor vivo puede tropezar en tiempo de petición y necesitar una página de error.
Lo distintivo de la 500 es que recibe el error como prop, para que puedas registrarlo o adaptar el mensaje.
---
// src/pages/500.astro
interface Props { error: unknown }
const { error } = Astro.props;
console.error(error);
---
<html lang="es">
<head><title>Error del servidor</title></head>
<body>
<h1>Algo ha ido mal</h1>
<p>Estamos en ello. Intentalo de nuevo en unos minutos.</p>
</body>
</html>
La prop error es oro para tus registros y veneno para tu página pública. Un mensaje de excepción o una traza revelan rutas internas, versiones y a veces datos sensibles. Regístralo en el servidor con console.error o tu herramienta de observabilidad, pero muestra al usuario un texto sobrio y humano. Nunca vuelques el error crudo en el HTML de producción.
redirects: redirigir sin escribir código
Las URLs cambian con el tiempo: reorganizas una sección, renombras un producto, unificas dos páginas. Para que los enlaces antiguos no mueran, Astro ofrece la clave redirects en la configuración: un mapa declarativo de origen a destino, sin una línea de lógica.
export default defineConfig({
redirects: {
'/viejo': '/nuevo',
'/tienda/[id]': '/productos/[id]',
'/panel': { status: 302, destination: '/login' },
},
});
Tres formas conviven en ese ejemplo. La cadena simple redirige una URL a otra con un 301 —permanente— por defecto. Los segmentos dinámicos entre corchetes reenvían familias enteras conservando el parámetro: /tienda/42 acaba en /productos/42. Y la forma de objeto te deja fijar el código de estado —un 302 temporal para un desvío que quizá revoques—.
Las reglas de redirects se evalúan antes de intentar casar una página, de modo que una entrada aquí tiene prioridad sobre un fichero del mismo nombre en src/pages. Es la herramienta adecuada para mudanzas masivas y estables, que quieres declarar en un solo sitio y olvidar. Cuando el desvío depende de datos de la petición —quién eres, qué llevas en la sesión— no cabe en este mapa estático y hay que bajar al código.
El código no es un detalle burocrático: comunica intención a navegadores y buscadores. Un 301 dice esto se ha mudado para siempre, y los buscadores transfieren la autoridad a la nueva URL y la memorizan. Un 302 dice es temporal, no actualices tus enlaces. Usa 301 para reestructuraciones definitivas y reserva 302 para desvíos pasajeros como un mantenimiento o un flujo de acceso.
Redirigir desde el código y el modo de renderizado
A veces la decisión de redirigir no es fija, sino que depende de datos: un usuario sin sesión, un recurso movido dinámicamente. Para eso, dentro de una página o un endpoint tienes Astro.redirect, que devuelve una respuesta de redirección que debes retornar.
---
// src/pages/panel.astro
const sesion = Astro.cookies.get('sesion');
if (!sesion) {
return Astro.redirect('/login', 302);
}
---
<h1>Panel privado</h1>
El detalle que más veces muerde es el return. Astro.redirect no interrumpe la ejecución por sí solo: construye una respuesta de redirección, pero solo surte efecto si la devuelves. Olvidar el return deja que el código siga y renderice la página que creías haber evitado —el panel privado se pinta igual, sin sesión—. Piensa en Astro.redirect como en producir un billete de salida: tenerlo en la mano no te saca de la sala; hay que entregarlo.
Cómo se materializa una redirección depende del modo de renderizado, y conviene tenerlo claro. En un sitio estático, no hay servidor que emita un 301 de verdad: Astro genera para cada redirección una pequeña página HTML con una meta-etiqueta de refresco —o, si tu adaptador lo soporta, un fichero de configuración que el host traduce a redirecciones nativas—. En renderizado bajo demanda, la redirección es una respuesta HTTP real, con su código y su cabecera Location, tal como la esperarías.
flowchart TD
N[peticion a una URL] --> M{existe la ruta}
M -->|si| OK[renderiza la pagina]
M -->|no| NF[pagina 404]
OK --> ERR{error al renderizar}
ERR -->|no| RESP[respuesta correcta]
ERR -->|si bajo demanda| SV[pagina 500]
R[regla en redirects] --> RED[redireccion 301 o 302]
style N fill:#89b4fa,color:#11111b
style RESP fill:#a6e3a1,color:#11111b
style NF fill:#f9e2af,color:#11111b
style SV fill:#f38ba8,color:#11111bJunto a las redirecciones existe una operación emparentada pero distinta: la reescritura, con Astro.rewrite. Una redirección cambia la URL del navegador y provoca una segunda petición; una reescritura mantiene la URL visible y sirve, por dentro, el contenido de otra ruta. Usa redirección cuando quieras que el visitante acabe en otra dirección, y reescritura cuando quieras servir otro contenido sin mover la barra de direcciones.
Las páginas de error y las redirecciones parecen apéndices menores del enrutado, pero son justo donde un sistema de rutas demuestra su madurez. La calidad se mide en los bordes: qué ocurre cuando la ruta no existe, cuando el render falla, cuando la URL de ayer ya no es la de hoy. Astro trata esos bordes como rutas de primera clase —un 404 y un 500 son páginas normales, una redirección es una entrada declarativa— en lugar de esconderlos tras mensajes genéricos que nadie controla. Detrás hay una idea que todo el que publica en la web debería interiorizar: una URL es una promesa. Cuando alguien enlaza a tu página, guarda su dirección o la comparte, cuenta con que seguirá ahí. Romper esa promesa sin más —dejar morir un enlace, mostrar una traza cruda— es una pequeña traición a quien confió en tu dirección. Las redirecciones son la forma de honrar la promesa aunque la estructura cambie: el contenido se mudó, pero el camino viejo sigue llevando a él. Y una buena página de error es cortesía en el peor momento: reconoce el fallo, no culpa al visitante y le ofrece una salida. Diseñar bien estos bordes no es pulir detalles cosméticos; es aceptar que los sistemas fallan y las cosas cambian, y decidir que, cuando ocurra, tu sitio se comportará con dignidad en lugar de abandonar al que llegó hasta él.
- Crea
src/pages/404.astrocon tu layout y un enlace al inicio; endev, visita una URL inexistente y compruébalo. - Añade una entrada a
redirectsque mande/viejoa/nuevocon un301y verifica el desvío. - Declara una redirección dinámica con
[slug]y confirma que conserva el parámetro entre origen y destino. - Razona por qué
src/pages/500.astrosolo actúa en renderizado bajo demanda y qué información delerrorconviene, o no, mostrar.