View Transitions y Animaciones de Navegación
Astro incluye soporte de primera clase para la API de View Transitions, permitiendo crear experiencias de usuario fluidas, dinámicas y con transiciones tipo Single Page Application (SPA) sin renunciar a la arquitectura Zero-JS basada en HTML estático.
1. ¿Qué son las View Transitions? #
Tradicionalmente, cuando un usuario hace clic en un enlace a otra página:
- La pantalla se vuelve blanca momentáneamente.
- El navegador descarga el nuevo HTML, CSS y JS desde cero.
- Se vuelve a renderizar toda la página, perdiendo el estado visual.
Con View Transitions, Astro intercepta la navegación del lado del cliente, solicita el HTML de la nueva página en segundo plano e interpola suavemente los elementos comunes mediante animaciones CSS de alto rendimiento.
2. Activación en el Layout con ClientRouter #
Para activar la navegación instantánea en todo el sitio, importa e inserta el componente <ClientRouter /> (llamado <ViewTransitions /> en versiones anteriores de Astro) dentro de la etiqueta <head> de tu layout principal:
📄 src/layouts/BaseLayout.astro
1--- 2import { ClientRouter } from 'astro:transitions'; 3const { title } = Astro.props; 4--- 5 6<html lang="es"> 7 <head> 8 <meta charset="UTF-8" /> 9 <title>{title}</title> 10 <ClientRouter /> 11 </head> 12 <body> 13 <slot /> 14 </body> 15</html>
✅ Con esta única línea, todas las etiquetas <a href="..."> del sitio navegarán de forma instantánea sin recarga brusca.
3. Animación de elementos compartidos (transition:name) #
El superpoder visual más impactante es conectar visualmente un elemento de la página origen con otro en la página destino mediante el atributo transition:name.
Ejemplo: Imagen de portada de un Blog #
En la lista de posts (/blog):
1--- 2// src/pages/blog/index.astro 3--- 4<a href={`/blog/${post.slug}`}> 5 <img 6 src={post.data.image} 7 alt={post.data.title} 8 transition:name={`hero-image-${post.slug}`} 9 class="w-48 h-32 rounded-lg" 10 /> 11 <h2 transition:name={`hero-title-${post.slug}`}>{post.data.title}</h2> 12</a>
En la vista de detalle (/blog/[slug]):
1--- 2// src/pages/blog/[slug].astro 3--- 4<article> 5 <img 6 src={post.data.image} 7 alt={post.data.title} 8 transition:name={`hero-image-${post.slug}`} 9 class="w-full h-80 rounded-2xl shadow-xl" 10 /> 11 <h1 transition:name={`hero-title-${post.slug}`}>{post.data.title}</h1> 12 <p>{post.body}</p> 13</article>
✨ Al hacer clic, la imagen y el título se expanden y flotan suavemente de su tamaño pequeño en la lista a su posición final en el artículo.
TIP
El valor detransition:namedebe ser único en la página actual para que el navegador sepa qué elementos emparejar.
4. Tipos de animación (transition:animate) #
Astro proporciona animaciones predefinidas que puedes aplicar a cualquier contenedor o elemento:
1<!-- Desvanecimiento suave --> 2<main transition:animate="fade"> 3 <slot /> 4</main> 5 6<!-- Deslizamiento lateral --> 7<div transition:animate="slide"> 8 <p>Contenido deslizable</p> 9</div> 10 11<!-- Sin animación (cambio instantáneo) --> 12<header transition:animate="none"> 13 <nav>...</nav> 14</header>
5. Persistencia de estado con transition:persist #
Si tienes elementos interactivos como un reproductor de música/audio, un vídeo o un buscador con texto introducido, puedes evitar que se destruyan o se reinicien al navegar entre páginas agregando transition:persist:
1--- 2// src/components/AudioPlayer.astro 3--- 4<aside transition:persist="mini-reproductor" class="fixed bottom-4 right-4 bg-black p-4 text-white rounded-xl"> 5 <p>Reproduciendo Podcast...</p> 6 <audio controls src="/audio/capitulo-1.mp3"></audio> 7</aside>
🎵 El audio seguirá reproduciéndose sin cortes aunque el usuario visite diferentes páginas del sitio.
6. Ciclo de vida y scripts con astro:page-load #
Cuando se usan View Transitions, el evento tradicional window.onload o DOMContentLoaded solo se ejecuta en la carga inicial. Para inicializar librerías (gráficos, modales, tooltips) en cada cambio de ruta, escucha el evento astro:page-load:
1<script> 2 document.addEventListener('astro:page-load', () => { 3 console.log('Nueva página cargada mediante View Transitions'); 4 // Inicializar tooltips o animaciones JS aquí 5 }); 6</script>
Resumen del tema
Conceptos clave #
- Enrutador de cliente (
<ClientRouter />): componente deastro:transitionsque intercepta navegación en enlaces internos y actualiza el DOM dinámicamente. - Morfismo de elementos (
transition:name): identificador compartido entre páginas para animar posición, escala y forma de un elemento continuo. - Persistencia en el DOM (
transition:persist): directiva que previene el desmontaje de componentes multimedia o formularios entre transiciones de ruta. - Animaciones integradas (
transition:animate): opcionesfade,slideynonepara transiciones de contenedores. - Evento
astro:page-load: disparador estándar del ciclo de vida para re-ejecutar código JavaScript tras cada cambio de página.
Qué debes recordar #
Añade <ClientRouter /> en tu layout base y usa transition:name para morphing de portadas y transition:persist para reproductores continuos sin perder rendimiento estático.