next-themes and Tailwind CSS. Users can toggle between light, dark, and system themes with their preference persisted across sessions.
Overview
The theme system provides:- Light and dark mode with instant switching
- System preference detection that respects OS settings
- Persistent user selection stored in localStorage
- No flash of unstyled content on page load
- Tailwind integration using
dark:class modifiers
Architecture
ThemeProvider Setup
The theme system is initialized in the root layout:app/layout.tsx
How the theme is applied. Using
"class" enables Tailwind’s dark: modifiers.The default theme when no preference is stored.
"system" follows the OS preference.Allows detecting and using the system theme preference.
Prevents CSS transitions during theme switches for instant changes. Set to
true to avoid visual glitches.The
suppressHydrationWarning prop on the <html> element prevents hydration warnings caused by next-themes modifying the class attribute before React hydrates.ThemeSwitcher Component
The header includes a theme toggle button:components/theme-switcher.tsx
Tailwind Configuration
Enabling Dark Mode
Dark mode is enabled intailwind.config.ts:
tailwind.config.ts
Set to
"class" to use next-themes with Tailwind’s dark: modifier. The alternative "media" uses CSS media queries only.Dark Mode Color Palette
Define colors that work in both themes:tailwind.config.ts
Styling Components for Dark Mode
Basic Dark Mode Styles
Use Tailwind’sdark: modifier to apply dark mode styles:
Component Example
Create theme-aware components:components/ui/card.tsx
Complex Color Transitions
Handle colors that need different values in each theme:CSS Variables Approach
For dynamic theming, use CSS variables:Define Variables
app/globals.css
Use in Tailwind
Reference CSS variables in Tailwind config:tailwind.config.ts
Apply in Components
Advanced Theme Patterns
Multi-Theme Dropdown
Create a full theme selector with light, dark, and system options:components/theme-selector.tsx
Detecting System Theme
Access the resolved theme (accounting for system preference):Conditional Rendering
Render different content based on theme:Custom Color Schemes
Creating Theme Variants
Define multiple color schemes:app/globals.css
Best Practices
Always Use Semantic Colors
Always Use Semantic Colors
Use semantic color names like
background, foreground, border instead of specific colors like white or gray-900. This makes theme changes easier.Test Both Themes
Test Both Themes
Always test your UI in both light and dark modes. Colors that work in light mode may have insufficient contrast in dark mode.
Provide Sufficient Contrast
Provide Sufficient Contrast
Ensure WCAG AA contrast ratios (4.5:1 for text) in both themes. Use tools like Contrast Checker.
Avoid Transition Flickering
Avoid Transition Flickering
Set
disableTransitionOnChange to prevent CSS transitions from animating during theme switches, which can cause visual glitches.Handle Images Appropriately
Handle Images Appropriately
For logos and images, provide theme-specific variants or use images that work in both themes. Transparent PNGs and SVGs work best.
Accessibility Considerations
Respecting System Preferences
The defaultsystem theme respects the user’s OS-level preference:
Reduced Motion
Respect theprefers-reduced-motion setting:
Focus Indicators
Ensure focus indicators are visible in both themes:Troubleshooting
Flash of Unstyled Content
Flash of Unstyled Content
If you see a flash when the page loads, ensure
suppressHydrationWarning is on the <html> element:Theme Not Persisting
Theme Not Persisting
Ensure
next-themes can access localStorage. Check browser settings and privacy modes. The theme is stored in localStorage.theme.Icons Not Switching
Icons Not Switching
If theme toggle icons don’t switch properly, verify both icons are present and CSS transitions are working:
Hydration Mismatch
Hydration Mismatch
If you see hydration errors, ensure theme-dependent components use the mounted check:
Next Steps
Branding & Styling
Apply your brand colors and visual identity
App Configuration
Configure navigation and layout settings
Component Library
Explore theme-aware UI components
Custom Pages
Create custom pages with dark mode support

