From 09ef32835771ff16cd732fe317ba2ba2542c5839 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 10 Jul 2026 00:21:00 +0000 Subject: [PATCH] Fix embed ignoring explicit ?theme override on single-theme sites (RND-11571) resolveEmbeddableTheme checked the non-toggeable branch before the explicit forcedTheme, so a site with the theme toggle disabled silently ignored the embed's ?theme=light/dark (SDK colorScheme) request. Reorder so an explicit override always wins, which is the only reliable way to force the scheme from a mobile webview that can't run JS. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01MN7HAu1vHzuFeND4UCRCBo --- .changeset/rnd-11571-embed-force-theme.md | 5 +++++ packages/gitbook/src/lib/embeddable.test.ts | 21 +++++++++++++++++++-- packages/gitbook/src/lib/embeddable.ts | 20 ++++++++++++-------- 3 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 .changeset/rnd-11571-embed-force-theme.md diff --git a/.changeset/rnd-11571-embed-force-theme.md b/.changeset/rnd-11571-embed-force-theme.md new file mode 100644 index 000000000..6ba7d12e4 --- /dev/null +++ b/.changeset/rnd-11571-embed-force-theme.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Embed: an explicit `?theme=light` / `?theme=dark` (the SDK `colorScheme` option) now reliably forces the embed's color scheme, even on sites where the theme toggle is disabled. Previously single-theme sites ignored the requested scheme. diff --git a/packages/gitbook/src/lib/embeddable.test.ts b/packages/gitbook/src/lib/embeddable.test.ts index c63b59545..2df3c7d92 100644 --- a/packages/gitbook/src/lib/embeddable.test.ts +++ b/packages/gitbook/src/lib/embeddable.test.ts @@ -146,14 +146,31 @@ describe('resolveEmbeddableTheme', () => { }); }); - it('keeps the site theme for single-theme sites', () => { + it('keeps the site theme for single-theme sites without an override', () => { expect( resolveEmbeddableTheme( createCustomization({ toggeable: false, default: CustomizationDefaultThemeMode.Light, + }) + ) + ).toEqual({ + htmlTheme: CustomizationDefaultThemeMode.Light, + defaultTheme: CustomizationDefaultThemeMode.Light, + forcedTheme: CustomizationDefaultThemeMode.Light, + }); + }); + + it('honors an explicit override on single-theme sites (RND-11571)', () => { + // A `?theme=light` embed on a site with the theme toggle disabled must still + // force the requested scheme, since a webview can only pass it via the URL. + expect( + resolveEmbeddableTheme( + createCustomization({ + toggeable: false, + default: CustomizationDefaultThemeMode.Dark, }), - CustomizationDefaultThemeMode.Dark + CustomizationDefaultThemeMode.Light ) ).toEqual({ htmlTheme: CustomizationDefaultThemeMode.Light, diff --git a/packages/gitbook/src/lib/embeddable.ts b/packages/gitbook/src/lib/embeddable.ts index 4687d51fe..0fdb71c30 100644 --- a/packages/gitbook/src/lib/embeddable.ts +++ b/packages/gitbook/src/lib/embeddable.ts @@ -46,6 +46,18 @@ export function resolveEmbeddableTheme( customization: Pick, forcedTheme?: CustomizationDefaultThemeMode | null ) { + // An explicit override (the embed's `?theme=` / `colorScheme` option) always wins, even for + // single-theme sites: the embedder is deliberately matching the color scheme of their own page, + // and a webview can only pass it via the URL. This must be checked before the toggeable branch, + // otherwise a site with the theme toggle disabled silently ignores the requested scheme. RND-11571 + if (forcedTheme) { + return { + htmlTheme: forcedTheme, + defaultTheme: forcedTheme, + forcedTheme, + }; + } + if (!customization.themes.toggeable) { const mode = customization.themes.default; return { @@ -56,14 +68,6 @@ export function resolveEmbeddableTheme( }; } - if (forcedTheme) { - return { - htmlTheme: forcedTheme, - defaultTheme: forcedTheme, - forcedTheme, - }; - } - return { htmlTheme: CustomizationDefaultThemeMode.System, defaultTheme: CustomizationDefaultThemeMode.System,