Step 1: Configure Tailwind
// tailwind.config.js
module.exports = {
darkMode: 'class', // or 'media' for system preference
// ...
}
Step 2: Create Theme Provider
'use client';
import { createContext, useContext, useEffect, useState } from 'react';
const ThemeContext = createContext({
theme: 'light',
toggleTheme: () => {},
});
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
useEffect(() => {
// Check localStorage or system preference
const saved = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const initial = saved || (prefersDark ? 'dark' : 'light');
setTheme(initial);
document.documentElement.classList.toggle('dark', initial === 'dark');
}, []);
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
document.documentElement.classList.toggle('dark', newTheme === 'dark');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
export const useTheme = () => useContext(ThemeContext);
Step 3: Theme Toggle Button
'use client';
import { useTheme } from './ThemeProvider';
export function ThemeToggle() {
const { theme, toggleTheme } = useTheme();
return (
<button
onClick={toggleTheme}
className="p-2 rounded-lg bg-gray-200 dark:bg-gray-700"
>
{theme === 'light' ? '🌙' : '☀️'}
</button>
);
}
Step 4: Use Dark Classes
<div className="bg-white dark:bg-gray-900">
<h1 className="text-gray-900 dark:text-white">
Hello World
</h1>
<p className="text-gray-600 dark:text-gray-300">
This changes based on theme
</p>
</div>
Step 5: Prevent Flash
// Add to <head> in layout
<script dangerouslySetInnerHTML={{
__html: `
(function() {
const theme = localStorage.getItem('theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.classList.toggle('dark', theme === 'dark');
})();
`
}} />
Comments (0)
Leave a Comment
No comments yet. Be the first to share your thoughts!