@yarso/astro-theme-toggler
v1.1.0
Published
Astro Theme Toggler with Vanilla JS
Maintainers
Readme
Theme Toggler for Astro 🚀
Simple, minimal, and optimized theme toggler utility for Astro with vanilla JS.
When I started in frontend, I used to handle this kind of thing with React, which isn't "bad" but it's definitely not optimal. I use this same group of utilities in each static project I make, so I decided to create a library for my own use.
Feel free to use it, modify it, report issues, or just complain about it.
[!WARNING]
This utility uses.darkclasses to handle themes. It's mainly designed to be used with Tailwind.
Installation
pnpm add @yarso/astro-theme-togglerUsage
Load Theme on Page Load
Use the LoadTheme component inside your head tag in your layout to load the theme from the user's browser preferences.
import { LoadTheme } from "@yarso/astro-theme-toggler"<head>
<LoadTheme />
<!-- other head elements -->
</head>[!NOTE]
This component prevents theme flashing (FOUC - Flash of Unstyled Content) on page reloads.
Create a Theme Toggler
There are two ways to create a theme toggler:
Option 1: Using ThemeToggler (Pre-built Button)
Import ThemeToggler, which provides a customizable <button> element. Add two child elements: the first for light theme content, the second for dark theme content.
import { ThemeToggler } from "@yarso/astro-theme-toggler"<header>
<a href="/">My Web App</a>
<ThemeToggler>
<span>🌞 Light</span>
<span>🌙 Dark</span>
</ThemeToggler>
</header>You can style the button with any attributes:
<ThemeToggler class="my-custom-class" aria-label="Toggle theme">
<span>🌞</span>
<span>🌙</span>
</ThemeToggler>Option 2: Using ThemeTogglerWrapper (Custom Button)
If you already have your own UI component library or want to maintain design consistency, use ThemeTogglerWrapper to add theme toggling logic to your existing button component.
import { Button } from "@/components/ui/Button"
import { ThemeTogglerWrapper } from "@yarso/astro-theme-toggler"<header>
<a href="/">My Web App</a>
<ThemeTogglerWrapper>
<Button>
<span>🌞 Light</span>
<span>🌙 Dark</span>
</Button>
</ThemeTogglerWrapper>
</header>How It Works
- Theme persistence: Saves user preference to localStorage
- System preference detection: Respects prefers-color-scheme media query
- Zero dependencies: Pure vanilla JavaScript
- Optimized performance: Uses requestAnimationFrame and debouncing
- No flash: Inline script prevents theme flashing on load
- Multiple togglers: Now supported automatically!
Customization
The components apply a .dark class to the document root. You can customize your styles accordingly:
/* Light theme (default) */
body {
background-color: white;
color: black;
}
/* Dark theme */
.dark body {
background-color: #0f172a;
color: white;
}Or with Tailwind CSS:
<div class="bg-white dark:bg-slate-900 text-black dark:text-white">
Content here
</div>Known Limitations
This is a custom implementation designed to suit specific requirements, so yeah, there are a lot of areas for improvement.
License
MIT License.
