[bug]: Astro Dark Mode Guide Flicker
Describe the bug
Based on the current dark mode setup guide for Astro, https://ui.shadcn.com/docs/dark-mode/astro, there's a flicker of the dark mode on the page as seen in the video below.
The flicker happens and is noticeable when my theme is set to dark or system (that is dark mode).
The issue seems to be tied to the src/components/ModeToggle.tsx component and the dark mode state changes.
Basically, the theme is initially set to "theme-light" in React.useState,
const [theme, setThemeState] = React.useState<
"theme-light" | "dark" | "system"
>("theme-light");
I tried to console.log the theme in the second React.useEffect check where the dark mode is set on the documentElement and realised that initially, it's set to "theme-light" which comes from the initial theme state and then, it's later set to the dark(as seen in the console in the video). This causes a flicker as the theme will first be set to light mode by removing the dark class from the documentElement and then later added. Even though, it's quite fast, it's still noticeable as a flicker on the page.
I suggest an update to the documentation by initially setting the theme to null (so in typescript, we can accept null as one of the union types), then performing a null check and only updating the documentElement if the theme is not null. This fixes the issue of flicker in dark mode. Updated code below:
const [theme, setThemeState] = React.useState<
"theme-light" | "dark" | "system" | null
>(null);
React.useEffect(() => {
const isDarkMode = document.documentElement.classList.contains("dark");
setThemeState(isDarkMode ? "dark" : "theme-light");
}, []);
React.useEffect(() => {
if (theme !== null) {
const isDark =
theme === "dark" ||
(theme === "system" &&
window.matchMedia("(prefers-color-scheme: dark)").matches);
document.documentElement.classList[isDark ? "add" : "remove"]("dark");
}
}, [theme]);
Screen recording 2024-10-20 21.59.36.webm
Affected component/components
Dark Mode
How to reproduce
- Go to shadcn astro installation to set up a new astro project with shadcn.
- Setup dark mode with the shadcn astro dark mode documentation.
- Change your theme to dark mode and refresh page
Codesandbox/StackBlitz link
https://stackblitz.com/edit/withastro-astro-awu25v?file=src%2Fcomponents%2FModeToggle.tsx
Logs
// console logs
{
"theme": "theme-light"
}
{
"theme": "dark"
}
System Info
-
Before submitting
- [X] I've made research efforts and searched the documentation
- [X] I've searched for existing issues
Same issue here. Any update?
Same issue here. Any update?
You can try the solution I suggested. Does that work?
Any updates on this? Is there any native way to initially render dark theme? I have same issue with remix(react router framework)
I'm seeing the same issue with next-theme provider
Thanks, your solution for Astro.js works!
Any updates?