Skip to content

Fix flash for site with dark default mode #3050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/spicy-snails-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitbook": patch
---

Fix flash when loading sites with dark mode as default theme
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default async function SiteDynamicLayout({
const forcedTheme = await getThemeFromMiddleware();

return (
<CustomizationRootLayout customization={context.customization}>
<CustomizationRootLayout forcedTheme={forcedTheme} customization={context.customization}>
<SiteLayout
context={context}
forcedTheme={forcedTheme}
Expand Down
9 changes: 8 additions & 1 deletion packages/gitbook-v2/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,14 @@ async function serveSiteRoutes(requestURL: URL, request: NextRequest) {
routeType,
mode,
encodeURIComponent(siteURLWithoutProtocol),
encodeURIComponent(rison.encode(siteURLData)),
encodeURIComponent(
rison.encode({
...siteURLData,
// The pathname is passed as the next segment of the route and should not cause this segment to change
// based on the page being visited
pathname: '<DO_NOT_USE>',
})
),
pathname,
].join('/');

Expand Down
7 changes: 3 additions & 4 deletions packages/gitbook/src/components/PDF/PDFPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
type CustomizationSettings,
type Revision,
type RevisionPageDocument,
type RevisionPageGroup,
Expand All @@ -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';
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -180,7 +179,7 @@ export async function PDFPage(props: {

async function PDFSpaceIntro(props: {
space: Space;
customization: CustomizationSettings | SiteCustomizationSettings;
customization: SiteCustomizationSettings;
}) {
const { space, customization } = props;

Expand Down
4 changes: 2 additions & 2 deletions packages/gitbook/src/components/PDF/PDFRootLayout.tsx
Original file line number Diff line number Diff line change
@@ -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';

/**
Expand All @@ -14,7 +14,7 @@ export async function PDFRootLayout(props: {
return (
<CustomizationRootLayout
customization={
'customization' in context ? context.customization : defaultCustomizationForSpace()
'customization' in context ? context.customization : defaultCustomization()
}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import {
CustomizationCorners,
CustomizationHeaderPreset,
CustomizationIconsStyle,
type CustomizationSettings,
CustomizationSidebarBackgroundStyle,
CustomizationSidebarListStyle,
CustomizationThemeMode,
type CustomizationThemedColor,
type CustomizationTint,
type SiteCustomizationSettings,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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'
: ''
)}
>
<head>
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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'
Expand Down
5 changes: 2 additions & 3 deletions packages/gitbook/src/components/TableOfContents/Trademark.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type {
CustomizationSettings,
SiteCustomizationSettings,
SiteInsightsTrademarkPlacement,
Space,
Expand All @@ -16,7 +15,7 @@ import { Link } from '../primitives';
*/
export function Trademark(props: {
space: Space;
customization: CustomizationSettings | SiteCustomizationSettings;
customization: SiteCustomizationSettings;
placement: SiteInsightsTrademarkPlacement;
}) {
return (
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions packages/gitbook/src/intl/server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CustomizationSettings, SiteCustomizationSettings } from '@gitbook/api';
import type { SiteCustomizationSettings } from '@gitbook/api';

import { type TranslationLanguage, languages } from './translations';

Expand All @@ -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;
Expand Down
50 changes: 31 additions & 19 deletions packages/gitbook/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -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: {
Expand All @@ -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,
},
pagination: {
advancedCustomization: {
enabled: true,
},
privacyPolicy: {},
socialPreview: {},
git: {
showEditLink: false,
},
inherit: false,
pagination: {
enabled: true,
},
trademark: {
enabled: true,
},
privacyPolicy: {
url: 'https://www.gitbook.com/privacy',
},
socialPreview: {},
};
}