Skip to content
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

Add support for custom fonts #2981

Merged
merged 1 commit into from
Mar 24, 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
6 changes: 6 additions & 0 deletions .changeset/little-geese-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"gitbook-v2": patch
"gitbook": patch
---

Add initial support for loading custom fonts
1 change: 1 addition & 0 deletions .github/composite/deploy-cloudflare/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ runs:
GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY
GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL
GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX
GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL
- name: Build worker
run: bun run turbo build:v2:cloudflare
shell: bash
Expand Down
2 changes: 2 additions & 0 deletions .github/composite/deploy-vercel/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ runs:
GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY
GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL
GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX
GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL
- name: Build Project Artifacts
run: bun run vercel build --target=${{ inputs.environment }} --token=${{ inputs.vercelToken }}
shell: bash
Expand All @@ -74,3 +75,4 @@ runs:
shell: bash
run: |
echo "URL: ${{ steps.deploy.outputs.deployment-url }}"
173 changes: 149 additions & 24 deletions bun.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/gitbook-v2/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const nextConfig = {
GITBOOK_ASSETS_PREFIX: process.env.GITBOOK_ASSETS_PREFIX,
GITBOOK_SECRET: process.env.GITBOOK_SECRET,
GITBOOK_IMAGE_RESIZE_SIGNING_KEY: process.env.GITBOOK_IMAGE_RESIZE_SIGNING_KEY,
GITBOOK_FONTS_URL: process.env.GITBOOK_FONTS_URL,

// Next.js envs
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY,
Expand Down
2 changes: 2 additions & 0 deletions packages/gitbook-v2/src/app/~gitbook/env/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
GITBOOK_APP_URL,
GITBOOK_ASSETS_URL,
GITBOOK_DISABLE_TRACKING,
GITBOOK_FONTS_URL,
GITBOOK_ICONS_URL,
GITBOOK_IMAGE_RESIZE_SIGNING_KEY,
GITBOOK_INTEGRATIONS_HOST,
Expand All @@ -25,6 +26,7 @@ export async function GET(_req: NextRequest) {
GITBOOK_API_URL,
GITBOOK_API_PUBLIC_URL,
GITBOOK_ASSETS_URL,
GITBOOK_FONTS_URL,
GITBOOK_ICONS_URL,
GITBOOK_USER_AGENT,
GITBOOK_INTEGRATIONS_HOST,
Expand Down
5 changes: 5 additions & 0 deletions packages/gitbook-v2/src/lib/env/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ export const GITBOOK_DISABLE_TRACKING = Boolean(
export const GITBOOK_INTEGRATIONS_HOST =
process.env.GITBOOK_INTEGRATIONS_HOST || 'integrations.gitbook.com';

/**
* Hostname for fonts.
*/
export const GITBOOK_FONTS_URL = process.env.GITBOOK_FONTS_URL || 'https://fonts.gitbook.com';

/**
* Endpoint to use for resizing images.
* It should be a Cloudflare domain with image resizing enabled.
Expand Down
5 changes: 3 additions & 2 deletions packages/gitbook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
"devDependencies": {
"@argos-ci/playwright": "^4.3.0",
"@cloudflare/next-on-pages": "1.13.7",
"vercel": "^39.3.0",
"@cloudflare/workers-types": "^4.20241230.0",
"@playwright/test": "^1.51.1",
"@types/js-cookie": "^3.0.6",
Expand All @@ -93,8 +92,10 @@
"jsonwebtoken": "^9.0.2",
"postcss": "^8",
"psi": "^4.1.0",
"stylelint": "^16.16.0",
"tailwindcss": "^3.4.0",
"ts-essentials": "^10.0.1",
"typescript": "^5.5.3"
"typescript": "^5.5.3",
"vercel": "^39.3.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import {
hexToRgb,
} from '@gitbook/colors';
import { IconStyle, IconsProvider } from '@gitbook/icons';
import * as ReactDOM from 'react-dom';

import { fontNotoColorEmoji, fonts, ibmPlexMono } from '@/fonts';
import { getFontData } from '@/fonts';
import { fontNotoColorEmoji, ibmPlexMono } from '@/fonts/default';
import { getSpaceLanguage } from '@/intl/server';
import { getAssetURL } from '@/lib/assets';
import { tcls } from '@/lib/tailwind';
Expand All @@ -31,7 +33,7 @@ import { ClientContexts } from './ClientContexts';

import '@gitbook/icons/style.css';
import './globals.css';
import { GITBOOK_ICONS_TOKEN, GITBOOK_ICONS_URL } from '@v2/lib/env';
import { GITBOOK_FONTS_URL, GITBOOK_ICONS_TOKEN, GITBOOK_ICONS_URL } from '@v2/lib/env';

/**
* Layout shared between the content and the PDF renderer.
Expand All @@ -48,6 +50,22 @@ export async function CustomizationRootLayout(props: {
const mixColor = getTintMixColor(customization.styling.primaryColor, tintColor);
const sidebarStyles = getSidebarStyles(customization);
const { infoColor, successColor, warningColor, dangerColor } = getSemanticColors(customization);
const fontData = getFontData(customization.styling.font);

// Preconnect and preload custom fonts if needed
if (fontData.type === 'custom') {
ReactDOM.preconnect(GITBOOK_FONTS_URL);
fontData.preloadSources
.flatMap((face) => face.sources)
.forEach(({ url, format }) => {
ReactDOM.preload(url, {
as: 'font',
crossOrigin: 'anonymous',
fetchPriority: 'high',
type: format ? `font/${format}` : undefined,
});
});
}

return (
<html
Expand All @@ -66,16 +84,18 @@ export async function CustomizationRootLayout(props: {
sidebarStyles.list && `sidebar-list-${sidebarStyles.list}`,
'links' in customization.styling && `links-${customization.styling.links}`,
fontNotoColorEmoji.variable,
typeof customization.styling.font === 'string'
? fonts[customization.styling.font].variable
: '',
ibmPlexMono.variable
ibmPlexMono.variable,
fontData.type === 'default' ? fontData.variable : 'font-custom'
)}
>
<head>
{customization.privacyPolicy.url ? (
<link rel="privacy-policy" href={customization.privacyPolicy.url} />
) : null}

{/* Inject custom font @font-face rules */}
{fontData.type === 'custom' ? <style>{fontData.fontFaceRules}</style> : null}

<style
nonce={
//Since I can't get the nonce to work for inline styles, we need to allow unsafe-inline
Expand Down
Loading