Next.js 15 Dark Mode with No Flicker
This project demonstrates how to implement a dark mode in Next.js 15 without the common flash of incorrect theme during page load.
The Dark Mode Flicker Problem
When implementing dark mode in Next.js (or any React application), there's often an undesirable "flash" where the wrong theme appears briefly before the correct theme is applied. This happens because:
- The page initially loads without any theme information
- Then the JavaScript loads and determines the correct theme
- Finally, the theme is applied, causing a visible switch
The Solution
We implement a flicker-free dark mode using a two-step approach:
1. Immediate Dark Mode Style
First, we add a style tag in the <head>
that immediately applies dark mode styles if the user's
system preferences are set to dark.
2. Cleanup Script
Then, we add a cleanup script that removes the temporary style once the theme system is properly initialized:
Why This Works
- Immediate Effect: The style tag applies dark mode instantly for users with dark mode preferences.
- No JavaScript Dependency: The initial theme is applied via CSS, so it works before JavaScript loads.
- Smooth Transition: The cleanup script ensures a smooth handoff to the theme system.
- No Flash: Users never see the wrong theme, regardless of their preferences.
Implementation
The solution is implemented in app/layout.tsx
. Check the file for the complete implementation includingthe ThemeProvider setup.