Implementa el modo oscuro en tu proyecto Astro con Tailwind CSS

August 16, 2023
3 min read
By Álvaro Jiménez

Tabla de Contenidos

Lista de todas las secciones en este post. Haz clic para ir a esa sección.

Cómo implementar el modo oscuro en Astro con Tailwind CSS

¿Quieres añadir modo oscuro a tu sitio Astro usando Tailwind CSS? Esta guía paso a paso te muestra cómo integrar perfectamente un interruptor de tema oscuro/claro fácil de usar con un código mínimo. Usaremos scripts en línea de Astro y Preact para una implementación suave y sin parpadeos.

Por qué es importante el modo oscuro

El modo oscuro reduce la fatiga visual, ahorra batería y mejora la accesibilidad. Con Tailwind CSS, habilitarlo es sencillo, simplemente alterna una clase dark en tu elemento HTML.

“El modo oscuro no es solo una tendencia, es una mejora de usabilidad.”

Configurando tu proyecto Astro

Instalar dependencias

Primero, crea un nuevo proyecto Astro y añade Tailwind CSS + Preact:

npm create astro@latest
npm install -D @astrojs/tailwind @astrojs/preact
npm install preact

Configurar Tailwind para modo oscuro

Actualiza tailwind.config.cjs para habilitar el modo oscuro basado en clases:

module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx,astro}"],
  darkMode: "class",
  theme: {},
  plugins: [],
};

Implementando la detección de tema

Script en línea para carga instantánea

Añade este script a tu Layout.astro para evitar el parpadeo del tema:

<script is:inline>
  const theme = (() => {
    if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
      return localStorage.getItem("theme");
    }
    if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
      return "dark";
    }
    return "light";
  })();
 
  document.documentElement.classList.toggle("dark", theme === "dark");
  localStorage.setItem("theme", theme);
</script>

Cómo funciona:

  • Comprueba la preferencia del usuario guardada en localStorage.
  • Recurre a las preferencias del sistema.
  • Aplica la clase dark instantáneamente.

Construyendo el interruptor de tema

Ejemplo de componente Preact

Crea un botón de alternancia con gestión de estado:

import { useEffect, useState } from "preact/hooks";
 
export default function ThemeToggle() {
  const [theme, setTheme] = useState("light");
 
  useEffect(() => {
    const savedTheme = localStorage.getItem("theme") || 
      (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
    setTheme(savedTheme);
  }, []);
 
  const toggleTheme = () => {
    const newTheme = theme === "light" ? "dark" : "light";
    setTheme(newTheme);
    document.documentElement.classList.toggle("dark", newTheme === "dark");
    localStorage.setItem("theme", newTheme);
  };
 
  return <button onClick={toggleTheme} aria-label="Toggle theme">{theme === "light" ? "🌙" : "🌞"}</button>;
}

Manejo de renderizado del lado del servidor

Evitando desajustes de hidratación

Para SSG, usa un estado mounted para retrasar el renderizado hasta que las API del lado del cliente estén disponibles:

const [isMounted, setIsMounted] = useState(false);
 
useEffect(() => {
  setIsMounted(true);
}, []);
 
if (!isMounted) return null; // Saltar renderizado SSR

Puntos clave:

  • Previene errores de localStorage durante la compilación.
  • Asegura una tematización consistente después de la hidratación.

Consejos finales para optimización

  • Usa el prefijo dark: de Tailwind para estilos de modo oscuro (por ejemplo, dark:bg-gray-900).
  • Prueba en dispositivos para asegurar la persistencia del tema.
  • Considera añadir una transición para un cambio más suave.

#TailwindCSS #Astro #DarkMode #WebDev