Skip to content

Commit 9fb233b

Browse files
grischeclaude
andcommitted
index: inline pre-paint script to prevent theme flash
Reads the stored theme preference synchronously in the document head and sets theme_night on <html> before any CSS resolves, so dark-mode users don't see a light-theme flash while Vite loads the main bundle. Read-only and wrapped in try/catch; the full theme module still owns writes and listeners. If localStorage access throws (sandboxed iframes, storage disabled, some file:// contexts), a nested try/catch still applies theme_night based on prefers-color-scheme alone, so OS-dark users also get the correct first paint without a late flip when lib/theme.ts boots. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d2ecf85 commit 9fb233b

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

index.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@
3030
<link rel="mask-icon" href="./mask-icon.svg" color="#FFFFFF" />
3131
<meta name="theme-color" content="#ffffff" />
3232

33+
<!-- Keep storage key ("meshviewer.theme") and class name ("theme_night") in sync with lib/theme.ts -->
34+
<script>
35+
try {
36+
var t = localStorage.getItem("meshviewer.theme");
37+
if (t === "dark" || (t !== "light" && matchMedia("(prefers-color-scheme: dark)").matches)) {
38+
document.documentElement.classList.add("theme_night");
39+
}
40+
} catch (e) {
41+
try {
42+
if (matchMedia("(prefers-color-scheme: dark)").matches) {
43+
document.documentElement.classList.add("theme_night");
44+
}
45+
} catch (_) {
46+
/* matchMedia unavailable; accept a light paint */
47+
}
48+
}
49+
</script>
3350
<script src="lib/index.ts" type="module"></script>
3451
</head>
3552
<body>

0 commit comments

Comments
 (0)