fix: theme.ts 所有函数添加 SSR 守卫,校验 localStorage 合法值

- setStoredTheme/applyTheme/initTheme 添加 typeof window 检查
- getStoredTheme 校验存储值是否在白名单中,防止非法 theme 值
This commit is contained in:
2026-02-26 20:11:21 +08:00
parent c4d1a122b2
commit 6488c19172
+8 -1
View File
@@ -1,13 +1,18 @@
export type Theme = "light" | "dark" | "system"; export type Theme = "light" | "dark" | "system";
const STORAGE_KEY = "nowhatever-theme"; const STORAGE_KEY = "nowhatever-theme";
const VALID_THEMES: Theme[] = ["light", "dark", "system"];
export function getStoredTheme(): Theme { export function getStoredTheme(): Theme {
if (typeof window === "undefined") return "system"; if (typeof window === "undefined") return "system";
return (localStorage.getItem(STORAGE_KEY) as Theme) || "system"; const stored = localStorage.getItem(STORAGE_KEY);
return stored && VALID_THEMES.includes(stored as Theme)
? (stored as Theme)
: "system";
} }
export function setStoredTheme(theme: Theme): void { export function setStoredTheme(theme: Theme): void {
if (typeof window === "undefined") return;
localStorage.setItem(STORAGE_KEY, theme); localStorage.setItem(STORAGE_KEY, theme);
applyTheme(theme); applyTheme(theme);
} }
@@ -21,11 +26,13 @@ function resolveTheme(theme: Theme): "light" | "dark" {
} }
export function applyTheme(theme: Theme): void { export function applyTheme(theme: Theme): void {
if (typeof window === "undefined") return;
const resolved = resolveTheme(theme); const resolved = resolveTheme(theme);
document.documentElement.setAttribute("data-theme", resolved); document.documentElement.setAttribute("data-theme", resolved);
} }
export function initTheme(): void { export function initTheme(): void {
if (typeof window === "undefined") return;
const theme = getStoredTheme(); const theme = getStoredTheme();
applyTheme(theme); applyTheme(theme);