fix(usercenter): 加 no-FOUC 内联脚本,消除刷新时明暗主题整页配色闪烁

layout 之前把 data-theme 硬编码 light、挂载后才由 UIProvider effect 应用保存的主题,
暗色偏好用户每次刷新先见浅色再翻暗色 = 整页配色重绘(叠加内容加载,观感"刷两次")。

照官网 Site.astro 做法:<head> 内联脚本在首屏渲染前读 localStorage(pg_uc_theme/
pg_uc_lang)设好 data-theme 与 html lang。/user/* CSP 允许 unsafe-inline 脚本,直接内联;
脚本为编译期常量、无插值、只读 localStorage,无 XSS 风险。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-08 15:04:23 +08:00
parent 101b31e073
commit 9a8fec2e9c
+9
View File
@@ -20,6 +20,15 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang="en" data-theme="light" suppressHydrationWarning>
<head>
{/* 首屏渲染前据 localStorage 设好 data-theme/lang,避免明暗主题(整页配色)在
挂载后才应用造成的 FOUC 闪烁。/user/* CSP 允许 'unsafe-inline' 脚本,故直接内联。
与官网 Site.astro 的 no-FOUC 脚本同法(键名用用户中心的 pg_uc_theme/pg_uc_lang)。 */}
<script
dangerouslySetInnerHTML={{
__html:
"(function(){try{var t=localStorage.getItem('pg_uc_theme');if(t==='dark'||t==='light')document.documentElement.dataset.theme=t;var l=localStorage.getItem('pg_uc_lang');if(l)document.documentElement.lang=l;}catch(e){}})()",
}}
/>
{/* 设计令牌单一真相源,原样链入(SRI 由构建期注入) */}
{/* eslint-disable-next-line @next/next/no-css-tags */}
<link rel="stylesheet" href={`${BASE_PATH}/colors_and_type.css`} />