Implementa el modo oscuro en tu sitio web con Astro y View Transitions
En sitios web con navegación SPA (Single Page Application), como los creados con Astro, es común enfrentarse a problemas al manejar temas entre páginas, especialmente cuando se busca mantener una experiencia fluida. Uno de los problemas más frecuentes es que los event listeners pueden perderse al navegar entre páginas, lo que afecta la funcionalidad de elementos como botones. Aquí veremos una solución que combina inicialización del tema, almacenamiento de preferencias y sincronización con View Transitions.
Paso 1: Inicialización del tema
El primer paso para implementar el modo oscuro es detectar y aplicar las preferencias del usuario. Esto incluye leer de localStorage y, si no hay un valor guardado, usar la preferencia del sistema.
getThemePreference
: Determina la preferencia del usuario basándose en localStorage o en el esquema de colores del sistema.applyTheme
: Aplica la clase dark al elementohtml
y actualiza el atributodata-theme
. También guarda la preferencia en localStorage.
Con esto aseguramos que el sitio respete la preferencia del usuario al cargar.
Parpadeo al cargar la página: Esto se resolvió inicializando el tema lo antes posible en el script para evitar el estilo predeterminado.
Paso 2: Agregar el toggle para cambiar el tema
El siguiente paso es crear un botón que permita alternar entre modo claro y oscuro de forma interactiva. Este botón debe funcionar correctamente incluso tras navegar entre páginas.
attachThemeToggle
: Busca el botón por su ID y asocia un evento click que alterna entre los modos claro y oscuro.
Este paso asegura que los usuarios puedan cambiar el tema manualmente.
Paso 3: Sincronización con transiciones de vista
Uno de los retos más grandes fue garantizar que el botón siga funcionando tras navegar entre páginas, ya que Astro reemplaza el DOM durante las transiciones. Esto lo resolvemos utilizando el evento astro:after-swap
.
astro:after-swap
: Este evento se dispara después de que Astro actualiza el DOM al navegar. Aquí volvemos a aplicar el tema y asociar el evento del botón al nuevo documento.
Botón que deja de funcionar tras navegar: Usamos astro:after-swap para reasociar el evento en el nuevo DOM.
Dónde insertar el código
Para garantizar que el código funcione correctamente, debes insertarlo a nivel del layout principal de tu proyecto Astro. Todo el script debe estar contenido dentro de un <script is:inline>
como se muestra en el siguiente ejemplo.
Conclusión
Con estos pasos, puedes agregar un modo oscuro funcional y sincronizado a tu sitio web con Astro. Esta implementación respeta las preferencias del usuario, permite alternar entre temas y soluciona problemas comunes como la pérdida de eventos con View Transitions.