Skip to content

Commit dedc654

Browse files
committed
use react dom to preload/preconnect
1 parent 8fda9d2 commit dedc654

File tree

15 files changed

+827
-245
lines changed

15 files changed

+827
-245
lines changed

.changeset/little-geese-provide.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"gitbook-v2": patch
3+
"gitbook": patch
4+
---
5+
6+
Add initial support for loading custom fonts

.github/composite/deploy-cloudflare/action.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ runs:
5050
GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY
5151
GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL
5252
GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX
53+
GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL
5354
- name: Build worker
5455
run: bun run turbo build:v2:cloudflare
5556
shell: bash

.github/composite/deploy-vercel/action.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ runs:
5555
GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY
5656
GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL
5757
GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX
58+
GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL
5859
- name: Build Project Artifacts
5960
run: bun run vercel build --target=${{ inputs.environment }} --token=${{ inputs.vercelToken }}
6061
shell: bash
@@ -74,3 +75,4 @@ runs:
7475
shell: bash
7576
run: |
7677
echo "URL: ${{ steps.deploy.outputs.deployment-url }}"
78+

bun.lock

+149-24
Large diffs are not rendered by default.

packages/gitbook-v2/next.config.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const nextConfig = {
3333
GITBOOK_ASSETS_PREFIX: process.env.GITBOOK_ASSETS_PREFIX,
3434
GITBOOK_SECRET: process.env.GITBOOK_SECRET,
3535
GITBOOK_IMAGE_RESIZE_SIGNING_KEY: process.env.GITBOOK_IMAGE_RESIZE_SIGNING_KEY,
36+
GITBOOK_FONTS_URL: process.env.GITBOOK_FONTS_URL,
3637

3738
// Next.js envs
3839
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY,

packages/gitbook-v2/src/app/~gitbook/env/route.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
GITBOOK_APP_URL,
88
GITBOOK_ASSETS_URL,
99
GITBOOK_DISABLE_TRACKING,
10+
GITBOOK_FONTS_URL,
1011
GITBOOK_ICONS_URL,
1112
GITBOOK_IMAGE_RESIZE_SIGNING_KEY,
1213
GITBOOK_INTEGRATIONS_HOST,
@@ -25,6 +26,7 @@ export async function GET(_req: NextRequest) {
2526
GITBOOK_API_URL,
2627
GITBOOK_API_PUBLIC_URL,
2728
GITBOOK_ASSETS_URL,
29+
GITBOOK_FONTS_URL,
2830
GITBOOK_ICONS_URL,
2931
GITBOOK_USER_AGENT,
3032
GITBOOK_INTEGRATIONS_HOST,

packages/gitbook-v2/src/lib/env/globals.ts

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ export const GITBOOK_DISABLE_TRACKING = Boolean(
6464
export const GITBOOK_INTEGRATIONS_HOST =
6565
process.env.GITBOOK_INTEGRATIONS_HOST || 'integrations.gitbook.com';
6666

67+
/**
68+
* Hostname for fonts.
69+
*/
70+
export const GITBOOK_FONTS_URL = process.env.GITBOOK_FONTS_URL || 'https://fonts.gitbook.com';
71+
6772
/**
6873
* Endpoint to use for resizing images.
6974
* It should be a Cloudflare domain with image resizing enabled.

packages/gitbook/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
"devDependencies": {
7474
"@argos-ci/playwright": "^4.3.0",
7575
"@cloudflare/next-on-pages": "1.13.7",
76-
"vercel": "^39.3.0",
7776
"@cloudflare/workers-types": "^4.20241230.0",
7877
"@playwright/test": "^1.51.1",
7978
"@types/js-cookie": "^3.0.6",
@@ -93,8 +92,10 @@
9392
"jsonwebtoken": "^9.0.2",
9493
"postcss": "^8",
9594
"psi": "^4.1.0",
95+
"stylelint": "^16.16.0",
9696
"tailwindcss": "^3.4.0",
9797
"ts-essentials": "^10.0.1",
98-
"typescript": "^5.5.3"
98+
"typescript": "^5.5.3",
99+
"vercel": "^39.3.0"
99100
}
100101
}

packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx

+26-6
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import {
2121
hexToRgb,
2222
} from '@gitbook/colors';
2323
import { IconStyle, IconsProvider } from '@gitbook/icons';
24+
import * as ReactDOM from 'react-dom';
2425

25-
import { fontNotoColorEmoji, fonts, ibmPlexMono } from '@/fonts';
26+
import { getFontData } from '@/fonts';
27+
import { fontNotoColorEmoji, ibmPlexMono } from '@/fonts/default';
2628
import { getSpaceLanguage } from '@/intl/server';
2729
import { getAssetURL } from '@/lib/assets';
2830
import { tcls } from '@/lib/tailwind';
@@ -31,7 +33,7 @@ import { ClientContexts } from './ClientContexts';
3133

3234
import '@gitbook/icons/style.css';
3335
import './globals.css';
34-
import { GITBOOK_ICONS_TOKEN, GITBOOK_ICONS_URL } from '@v2/lib/env';
36+
import { GITBOOK_FONTS_URL, GITBOOK_ICONS_TOKEN, GITBOOK_ICONS_URL } from '@v2/lib/env';
3537

3638
/**
3739
* Layout shared between the content and the PDF renderer.
@@ -48,6 +50,22 @@ export async function CustomizationRootLayout(props: {
4850
const mixColor = getTintMixColor(customization.styling.primaryColor, tintColor);
4951
const sidebarStyles = getSidebarStyles(customization);
5052
const { infoColor, successColor, warningColor, dangerColor } = getSemanticColors(customization);
53+
const fontData = getFontData(customization.styling.font);
54+
55+
// Preconnect and preload custom fonts if needed
56+
if (fontData.type === 'custom') {
57+
ReactDOM.preconnect(GITBOOK_FONTS_URL);
58+
fontData.preloadSources
59+
.flatMap((face) => face.sources)
60+
.forEach(({ url, format }) => {
61+
ReactDOM.preload(url, {
62+
as: 'font',
63+
crossOrigin: 'anonymous',
64+
fetchPriority: 'high',
65+
type: format ? `font/${format}` : undefined,
66+
});
67+
});
68+
}
5169

5270
return (
5371
<html
@@ -66,16 +84,18 @@ export async function CustomizationRootLayout(props: {
6684
sidebarStyles.list && `sidebar-list-${sidebarStyles.list}`,
6785
'links' in customization.styling && `links-${customization.styling.links}`,
6886
fontNotoColorEmoji.variable,
69-
typeof customization.styling.font === 'string'
70-
? fonts[customization.styling.font].variable
71-
: '',
72-
ibmPlexMono.variable
87+
ibmPlexMono.variable,
88+
fontData.type === 'default' ? fontData.variable : 'font-custom'
7389
)}
7490
>
7591
<head>
7692
{customization.privacyPolicy.url ? (
7793
<link rel="privacy-policy" href={customization.privacyPolicy.url} />
7894
) : null}
95+
96+
{/* Inject custom font @font-face rules */}
97+
{fontData.type === 'custom' ? <style>{fontData.fontFaceRules}</style> : null}
98+
7999
<style
80100
nonce={
81101
//Since I can't get the nonce to work for inline styles, we need to allow unsafe-inline

0 commit comments

Comments
 (0)