From d236bf029ca09210d6ec142d8a80f2a80dc90f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Wed, 26 Mar 2025 18:12:45 +0100 Subject: [PATCH] Fix flash for site with dark default mode (#3050) --- .changeset/spicy-snails-learn.md | 5 ++ .../[siteURL]/[siteData]/(content)/layout.tsx | 2 +- packages/gitbook-v2/src/middleware.ts | 9 +++- .../gitbook/src/components/PDF/PDFPage.tsx | 7 ++- .../src/components/PDF/PDFRootLayout.tsx | 4 +- .../RootLayout/CustomizationRootLayout.tsx | 20 ++++--- .../components/TableOfContents/Trademark.tsx | 5 +- packages/gitbook/src/intl/server.ts | 6 +-- packages/gitbook/src/lib/utils.ts | 52 ++++++++++++------- 9 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 .changeset/spicy-snails-learn.md diff --git a/.changeset/spicy-snails-learn.md b/.changeset/spicy-snails-learn.md new file mode 100644 index 000000000..ea3c39259 --- /dev/null +++ b/.changeset/spicy-snails-learn.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix flash when loading sites with dark mode as default theme diff --git a/packages/gitbook-v2/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx b/packages/gitbook-v2/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx index 8a21a46db..8934279f0 100644 --- a/packages/gitbook-v2/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx +++ b/packages/gitbook-v2/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx @@ -20,7 +20,7 @@ export default async function SiteDynamicLayout({ const forcedTheme = await getThemeFromMiddleware(); return ( - + ', + }) + ), pathname, ].join('/'); diff --git a/packages/gitbook/src/components/PDF/PDFPage.tsx b/packages/gitbook/src/components/PDF/PDFPage.tsx index da6b5d8ed..081fadc02 100644 --- a/packages/gitbook/src/components/PDF/PDFPage.tsx +++ b/packages/gitbook/src/components/PDF/PDFPage.tsx @@ -1,5 +1,4 @@ import { - type CustomizationSettings, type Revision, type RevisionPageDocument, type RevisionPageGroup, @@ -24,7 +23,7 @@ import { tString } from '@/intl/translate'; import { getPagePDFContainerId } from '@/lib/links'; import { resolvePageId } from '@/lib/pages'; import { tcls } from '@/lib/tailwind'; -import { defaultCustomizationForSpace } from '@/lib/utils'; +import { defaultCustomization } from '@/lib/utils'; import { type PDFSearchParams, getPDFSearchParams } from './urls'; import { PageControlButtons } from './PageControlButtons'; @@ -57,7 +56,7 @@ export async function PDFPage(props: { const pdfParams = getPDFSearchParams(new URLSearchParams(searchParams)); const customization = - 'customization' in baseContext ? baseContext.customization : defaultCustomizationForSpace(); + 'customization' in baseContext ? baseContext.customization : defaultCustomization(); const language = getSpaceLanguage(customization); // Compute the pages to render @@ -180,7 +179,7 @@ export async function PDFPage(props: { async function PDFSpaceIntro(props: { space: Space; - customization: CustomizationSettings | SiteCustomizationSettings; + customization: SiteCustomizationSettings; }) { const { space, customization } = props; diff --git a/packages/gitbook/src/components/PDF/PDFRootLayout.tsx b/packages/gitbook/src/components/PDF/PDFRootLayout.tsx index 6ebdd2f48..1aeb29d59 100644 --- a/packages/gitbook/src/components/PDF/PDFRootLayout.tsx +++ b/packages/gitbook/src/components/PDF/PDFRootLayout.tsx @@ -1,5 +1,5 @@ import { CustomizationRootLayout } from '@/components/RootLayout'; -import { defaultCustomizationForSpace } from '@/lib/utils'; +import { defaultCustomization } from '@/lib/utils'; import type { GitBookSiteContext, GitBookSpaceContext } from '@v2/lib/context'; /** @@ -14,7 +14,7 @@ export async function PDFRootLayout(props: { return ( {children} diff --git a/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx b/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx index 218dabac0..afa8e9960 100644 --- a/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx +++ b/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx @@ -2,9 +2,9 @@ import { CustomizationCorners, CustomizationHeaderPreset, CustomizationIconsStyle, - type CustomizationSettings, CustomizationSidebarBackgroundStyle, CustomizationSidebarListStyle, + CustomizationThemeMode, type CustomizationThemedColor, type CustomizationTint, type SiteCustomizationSettings, @@ -41,10 +41,11 @@ import { AnnouncementDismissedScript } from '../Announcement'; * It takes care of setting the theme and the language. */ export async function CustomizationRootLayout(props: { - customization: SiteCustomizationSettings | CustomizationSettings; + forcedTheme?: CustomizationThemeMode | null; + customization: SiteCustomizationSettings; children: React.ReactNode; }) { - const { customization, children } = props; + const { customization, forcedTheme, children } = props; const language = getSpaceLanguage(customization); const tintColor = getTintColor(customization); @@ -86,7 +87,12 @@ export async function CustomizationRootLayout(props: { 'links' in customization.styling && `links-${customization.styling.links}`, fontNotoColorEmoji.variable, ibmPlexMono.variable, - fontData.type === 'default' ? fontData.variable : 'font-custom' + fontData.type === 'default' ? fontData.variable : 'font-custom', + + // Set the dark/light class statically to avoid flashing and make it work when JS is disabled + (forcedTheme ?? customization.themes.default) === CustomizationThemeMode.Dark + ? 'dark' + : '' )} > @@ -181,7 +187,7 @@ export async function CustomizationRootLayout(props: { * If the tint color is not set or it is a space customization, it will return the default color. */ function getTintColor( - customization: CustomizationSettings | SiteCustomizationSettings + customization: SiteCustomizationSettings ): CustomizationTint['color'] | undefined { if ('tint' in customization.styling && customization.styling.tint) { return { @@ -228,7 +234,7 @@ function getTintMixColor( * If it is a space customization, it will return the default styles. */ function getSidebarStyles( - customization: CustomizationSettings | SiteCustomizationSettings + customization: SiteCustomizationSettings ): SiteCustomizationSettings['styling']['sidebar'] { if ('sidebar' in customization.styling) { return { @@ -248,7 +254,7 @@ function getSidebarStyles( * If it is a space customization, it will return the default styles. */ function getSemanticColors( - customization: CustomizationSettings | SiteCustomizationSettings + customization: SiteCustomizationSettings ): Pick< SiteCustomizationSettings['styling'], 'infoColor' | 'successColor' | 'warningColor' | 'dangerColor' diff --git a/packages/gitbook/src/components/TableOfContents/Trademark.tsx b/packages/gitbook/src/components/TableOfContents/Trademark.tsx index ff4b8eddc..3335e5f68 100644 --- a/packages/gitbook/src/components/TableOfContents/Trademark.tsx +++ b/packages/gitbook/src/components/TableOfContents/Trademark.tsx @@ -1,5 +1,4 @@ import type { - CustomizationSettings, SiteCustomizationSettings, SiteInsightsTrademarkPlacement, Space, @@ -16,7 +15,7 @@ import { Link } from '../primitives'; */ export function Trademark(props: { space: Space; - customization: CustomizationSettings | SiteCustomizationSettings; + customization: SiteCustomizationSettings; placement: SiteInsightsTrademarkPlacement; }) { return ( @@ -69,7 +68,7 @@ export function Trademark(props: { */ export function TrademarkLink(props: { space: Space; - customization: CustomizationSettings | SiteCustomizationSettings; + customization: SiteCustomizationSettings; placement: SiteInsightsTrademarkPlacement; }) { const { space, customization, placement } = props; diff --git a/packages/gitbook/src/intl/server.ts b/packages/gitbook/src/intl/server.ts index 737cc61b2..0aa201ef2 100644 --- a/packages/gitbook/src/intl/server.ts +++ b/packages/gitbook/src/intl/server.ts @@ -1,4 +1,4 @@ -import type { CustomizationSettings, SiteCustomizationSettings } from '@gitbook/api'; +import type { SiteCustomizationSettings } from '@gitbook/api'; import { type TranslationLanguage, languages } from './translations'; @@ -7,9 +7,7 @@ export * from './translate'; /** * Create the translation context for a space to use in the server components. */ -export function getSpaceLanguage( - customization: CustomizationSettings | SiteCustomizationSettings -): TranslationLanguage { +export function getSpaceLanguage(customization: SiteCustomizationSettings): TranslationLanguage { const fallback = languages.en; const { locale } = customization.internationalization; diff --git a/packages/gitbook/src/lib/utils.ts b/packages/gitbook/src/lib/utils.ts index 6b148a60e..7421ccb80 100644 --- a/packages/gitbook/src/lib/utils.ts +++ b/packages/gitbook/src/lib/utils.ts @@ -1,22 +1,30 @@ import * as api from '@gitbook/api'; /** - * Return the customizations with the default values for a space. + * Return the default customization settings for a site. */ -export function defaultCustomizationForSpace(): api.CustomizationSettings { +export function defaultCustomization(): api.SiteCustomizationSettings { return { - internationalization: { - inherit: false, - locale: api.CustomizationLocale.En, - }, styling: { - primaryColor: { - dark: '#346DDB', - light: '#346DDB', - }, + theme: api.CustomizationTheme.Clean, + primaryColor: { light: '#346DDB', dark: '#346DDB' }, + infoColor: { light: '#787878', dark: '#787878' }, + warningColor: { light: '#FE9A00', dark: '#FE9A00' }, + dangerColor: { light: '#FB2C36', dark: '#FB2C36' }, + successColor: { light: '#00C950', dark: '#00C950' }, corners: api.CustomizationCorners.Rounded, font: api.CustomizationDefaultFont.Inter, background: api.CustomizationBackground.Plain, + icons: api.CustomizationIconsStyle.Regular, + links: api.CustomizationLinksStyle.Default, + sidebar: { + background: api.CustomizationSidebarBackgroundStyle.Default, + list: api.CustomizationSidebarListStyle.Default, + }, + search: api.CustomizationSearchStyle.Subtle, + }, + internationalization: { + locale: api.CustomizationLocale.En, }, favicon: {}, header: { @@ -28,28 +36,32 @@ export function defaultCustomizationForSpace(): api.CustomizationSettings { }, themes: { default: api.CustomizationThemeMode.Light, - toggeable: false, + toggeable: true, }, - trademark: { + pdf: { enabled: true, }, feedback: { enabled: false, }, - pdf: { - enabled: true, - }, aiSearch: { enabled: true, }, + advancedCustomization: { + enabled: true, + }, + git: { + showEditLink: false, + }, pagination: { enabled: true, }, - privacyPolicy: {}, - socialPreview: {}, - git: { - showEditLink: false, + trademark: { + enabled: true, }, - inherit: false, + privacyPolicy: { + url: 'https://www.gitbook.com/privacy', + }, + socialPreview: {}, }; }