When to use this
If you’ve set darkMode: 'class' in tailwind.config.cjs, you need
something to actually flip that class on <html>. This snippet does that
with no React, no library — one inline script that runs before paint so
there’s no flash of the wrong theme.
The code
Drop this inline inside <head> (before <body>):
<script is:inline>
const KEY = 'theme';
const stored = localStorage.getItem(KEY);
const prefers = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (stored === 'dark' || (!stored && prefers)) {
document.documentElement.classList.add('dark');
}
</script>
Then your toggle button just calls:
function toggleTheme() {
const next = document.documentElement.classList.toggle('dark') ? 'dark' : 'light';
localStorage.setItem('theme', next);
}
How it works
The inline <script is:inline> runs before Astro hydrates anything, so
the class="dark" lands on <html> before the first paint. No theme flash.
The OS preference is the fallback only when localStorage is empty — that way once a user clicks your toggle their choice sticks across reloads and across OS theme changes.
Treat this snippet as the starting point — adapt names, types, and edge-case handling to your project. The shape is reusable; the details are yours.