fix(ui): apply persisted theme before first paint to avoid flash on reload

Theme was applied from the client store in useEffect (after hydration),
so a reload painted the default light theme for a frame before the
stored dark theme was reapplied. Add a blocking head script that reads
the persisted zustand theme key and sets the dark class on
documentElement before first paint, mirroring applyTheme() including
system -> prefers-color-scheme resolution.
This commit is contained in:
docaohieu2808
2026-09-02 20:05:18 +07:00
committed by decolua
parent b9c92cb83c
commit 925cb4aade

View File

@@ -32,6 +32,14 @@ export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<head>
{/* Apply persisted theme before first paint so a reload does not flash the
default (light) theme before the client store hydrates. Mirrors the
zustand-persist "theme" key and the `dark` class applyTheme() sets. */}
<script
dangerouslySetInnerHTML={{
__html: `(function(){try{var s=localStorage.getItem('theme');var t=s?(JSON.parse(s).state||{}).theme:'system';t=t||'system';var m=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t==='system'&&m)){document.documentElement.classList.add('dark')}}catch(e){}})();`,
}}
/>
<script
dangerouslySetInnerHTML={{
__html: `var d=document,r=d.documentElement,f=function(){r.classList.add('fonts-loaded')};if(d.fonts&&d.fonts.load){d.fonts.load('24px "Material Symbols Outlined"').then(f).catch(f);setTimeout(f,3000)}else{f()}`,