Set your Publisher ID in src/config/ads.ts to display live ads.
How To: Build a Dark Mode Toggle
Implement a flicker-free dark mode toggle using CSS Custom Properties, localStorage caching, and operating system preference detection.
The Three Pillars of a Rock-Solid Dark Mode System
A professional dark mode system consists of three coordinated layers:
--bg-primary, --text-primary, --border-color) scoped to the :root and html.dark selectors.localStorage so their chosen theme persists across page reloads and future visits.@media (prefers-color-scheme: dark) as the intelligent default when no explicit preference has been saved yet.Preventing the Infamous White Flash (FOUT)
A common bug in beginner implementations is the "Flash of Unstyled Theme" (FOUT) — where a dark mode user opens the page and sees a blinding white flash for 200ms before JavaScript initializes.
To prevent this, place an inline blocking script directly inside the document <head> BEFORE the <body> renders. Because it runs synchronously, the .dark class is attached before the DOM is painted on the screen.
<!-- Place directly in HTML <head> -->
<script>
(function() {
const saved = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (saved === 'dark' || (!saved && prefersDark)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
})();
</script>The Interactive Toggle Switch Handler
When the user clicks the theme toggle button, toggle the .dark class on document.documentElement and write the new state into localStorage.
function toggleDarkMode() {
const isDark = document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
// Update ARIA accessibility state
const btn = document.getElementById('theme-toggle-btn');
if (btn) {
btn.setAttribute('aria-pressed', isDark ? 'true' : 'false');
}
}You can also attach an event listener to window.matchMedia("(prefers-color-scheme: dark)") so that if the user changes their OS theme while your tab is open, your site adapts dynamically.
Set your Publisher ID in src/config/ads.ts to display live ads.
Test Yourself With Exercise
Where should the theme initialization script be placed to eliminate the white flash on page load?