Dark Mode
Adding dark mode to your Astro project.
Adding dark mode to your Astro project.
Create an inline theme script
Section titled “Create an inline theme script”---import "../styles/globals.css";---
<script is:inline> const getThemePreference = () => { if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) { return localStorage.getItem("theme"); } return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; }; const isDark = getThemePreference() === "dark"; document.documentElement.classList[isDark ? "add" : "remove"]("dark");
if (typeof localStorage !== "undefined") { const observer = new MutationObserver(() => { const isDark = document.documentElement.classList.contains("dark"); localStorage.setItem("theme", isDark ? "dark" : "light"); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"], }); }</script>
<html lang="en"> <body> <h1>Astro</h1> </body></html>Add a mode toggle
Section titled “Add a mode toggle”import * as React from "react";import { Moon, Sun } from "lucide-react";
import { Button } from "@/components/ui/button";import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger,} from "@/components/ui/dropdown-menu";
export function ModeToggle() { const [theme, setThemeState] = React.useState< "theme-light" | "dark" | "system" >("theme-light");
React.useEffect(() => { const isDarkMode = document.documentElement.classList.contains("dark"); setThemeState(isDarkMode ? "dark" : "theme-light"); }, []);
React.useEffect(() => { const isDark = theme === "dark" || (theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches); document.documentElement.classList[isDark ? "add" : "remove"]("dark"); }, [theme]);
return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline" size="icon"> <Sun className="h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" /> <Moon className="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" /> <span className="sr-only">Toggle theme</span> </Button> </DropdownMenuTrigger> <DropdownMenuContent align="end"> <DropdownMenuItem onClick={() => setThemeState("theme-light")}> Light </DropdownMenuItem> <DropdownMenuItem onClick={() => setThemeState("dark")}> Dark </DropdownMenuItem> <DropdownMenuItem onClick={() => setThemeState("system")}> System </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> );}Display the mode toggle
Section titled “Display the mode toggle”Place a mode toggle on your site to toggle between light and dark mode.
---import "../styles/globals.css";import { ModeToggle } from "@/components/ModeToggle";---
<!-- Inline script --><html lang="en"> <body> <h1>Astro</h1> <ModeToggle client:load /> </body></html>