From 968f41d68d897734d2388c61c6cf1380471ad3f9 Mon Sep 17 00:00:00 2001 From: Vladimir Eremin Date: Sat, 24 Oct 2026 20:48:59 +0300 Subject: [PATCH] fix(ssg): fix white header on dark theme and resolve critters CSP block (#66) ## Summary - **Critters preload**: Set `preload: false` in `ssgPlugin` to eliminate `onload="this.media='all'"` event handlers on external stylesheets, which violated Content Security Policy (`script-src 'self'` / `require-trusted-types-for 'script'`) and left the compiled stylesheet permanently blocked in `media="print"`. - **Dark theme selector retention**: Added `allowRules: [/\.dark/]` to Critters options so dark theme selectors and palette variables are preserved during critical CSS inlining. - **Immediate theme variables**: Initialized `--rb-background`, `--rb-base`, and `--rb-text` in `THEME_INIT_STYLES` for `:root` and `.dark` alongside background color to ensure components like `PageHead` instantly reflect the active theme. ## Verification - `pnpm typecheck`: Passed (0 errors) - `pnpm lint`: Passed (0 warnings) - `pnpm test`: Passed (all suites passed) - `pnpm build`: Passed (clean SSG generation) - Local Playwright browser test with dark color scheme verified `headerBg` is `rgb(20, 20, 20)` and zero CSP inline handler violations. --- packages/ssg/src/lib/config/ssg.ts | 6 ++++-- packages/ui/src/lib/theme/constants.ts | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/ssg/src/lib/config/ssg.ts b/packages/ssg/src/lib/config/ssg.ts index 8a834bc..600154f 100644 --- a/packages/ssg/src/lib/config/ssg.ts +++ b/packages/ssg/src/lib/config/ssg.ts @@ -134,10 +134,11 @@ export function ssgPlugin(): RsbuildPlugin { const Critters = _require('critters') as new (opts?: { path?: string; publicPath?: string; - preload?: string; + preload?: 'body' | 'media' | 'swap' | 'js' | 'js-lazy' | boolean; inlineFonts?: boolean; pruneSource?: boolean; reduceInlineStyles?: boolean; + allowRules?: (string | RegExp)[]; }) => { process(html: string): Promise }; const configuredAssetPrefix = @@ -147,10 +148,11 @@ export function ssgPlugin(): RsbuildPlugin { const critters = new Critters({ path: webDistPath, publicPath: configuredAssetPrefix, - preload: 'media', + preload: false, inlineFonts: false, pruneSource: false, reduceInlineStyles: false, + allowRules: [/\.dark/], }); for (const entryName of entryNames) { diff --git a/packages/ui/src/lib/theme/constants.ts b/packages/ui/src/lib/theme/constants.ts index 9a0ae20..84b39cd 100644 --- a/packages/ui/src/lib/theme/constants.ts +++ b/packages/ui/src/lib/theme/constants.ts @@ -10,7 +10,7 @@ export const THEME_INIT_SCRIPT = `(function(){try{var k='ermnvldmr/ui/lib/theme' * These align with the main palette in styles.css. */ export const THEME_INIT_STYLES = ` - :root { background-color: #fafafa; color: #262626; } - .dark { background-color: #141414; color: #f6f6f6; } + :root { --rb-background: #fafafa; --rb-base: #f6f6f6; --rb-text: #262626; background-color: #fafafa; color: #262626; } + .dark { --rb-background: #141414; --rb-base: #262626; --rb-text: #f6f6f6; background-color: #141414; color: #f6f6f6; } body { margin: 0; transition: background-color 0.2s ease; } `;