MW
Home Snippets Tailwind dark-mode toggle

Tailwind dark-mode toggle

Class-based dark mode in Astro/Tailwind without flash-of-wrong-theme.

TS tailwind dark-mode astro
tailwind-dark-toggle.ts
TS 14 lines
Requires: tailwindcss (darkMode: 'class')

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.

Pro tip

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.

Was this snippet helpful?

Get weekly notes in your inbox

Practical tips, tutorials and resources. No spam.