Theme flicker on page load
Answered
Iridescent shark posted this in #help-forum
Iridescent sharkOP
Hiya, I've implemented a theme switching system on my (tailwind) site. This works fine, however, I have a sort of FOUC situation where if any page is loaded it takes some time (~200ms) for the theme to load in. So if the user is using a dark theme, a light theme (the default), will appear first and then switch to dark.
How can I prevent this from happening? Here is the code I use:
How can I prevent this from happening? Here is the code I use:
// darkMode: "class"
// usage example: dark:text-white text-black
export default function Theme() {
const [theme, setTheme] = useState("light");
useEffect(() => {
const storedTheme = localStorage.getItem("theme");
if (storedTheme) {
setTheme(storedTheme);
}
}, []);
useEffect(() => {
const root = window.document.documentElement;
if (theme === "dark") {
root.classList.add("dark");
} else {
root.classList.remove("dark");
}
}, [theme]);
// ... theme switching logicAnswered by Asian black bear
You might want to use
next-themes which prevents FUOC altogether without you having to reinvent the wheel.7 Replies
Asian black bear
You might want to use
next-themes which prevents FUOC altogether without you having to reinvent the wheel.Answer
Iridescent sharkOP
Yeah, that's probably smarter.. I assume it integrates with tailwind if I'm reading this correctly?
Note! If you set the attribute of your Theme Provider to class for Tailwind next-themes will modify the class attribute on the html element. See With TailwindCSS.
Nevermind lol I didn't even see the 'with tailwind' section.. I'll go try it out!
Asian black bear
Yeah it will integrate with Tailwind when using the class attribute allowing you to use
dark:.Just make sure to pay attention when reading the readme which mentions that you have to use
suppressHydrationErrors on the root element which people often forget.Iridescent sharkOP
Where do I have to put that exactly? I have this in my layout now but I still receive the hydration errors. In the stack trace I see it being applied to the body as well (I'll try this: https://github.com/pacocoursey/next-themes?tab=readme-ov-file#avoid-hydration-mismatch)
return (
<html lang="en" suppressHydrationWarning>
<head />
<body>
<ThemeProvider attribute="class">
<Header />
{children}
</ThemeProvider>
</body>
</html>
);Yeah fixed it by waiting for it to be mounted, thanks!