From 09c7c307799b060ca712f91f5ee036d5bc1a04ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Fri, 10 Jan 2025 21:38:25 +0100 Subject: [PATCH 1/4] Try to fix error on og image generation (#2722) --- .changeset/fluffy-panthers-unite.md | 5 + .../~gitbook/ogimage/[pageId]/route.tsx | 200 +++++++++--------- packages/gitbook/src/fonts/index.ts | 18 ++ 3 files changed, 125 insertions(+), 98 deletions(-) create mode 100644 .changeset/fluffy-panthers-unite.md diff --git a/.changeset/fluffy-panthers-unite.md b/.changeset/fluffy-panthers-unite.md new file mode 100644 index 000000000..6f7ef7668 --- /dev/null +++ b/.changeset/fluffy-panthers-unite.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Try to fix error on og image generation diff --git a/packages/gitbook/src/app/(site)/(core)/~gitbook/ogimage/[pageId]/route.tsx b/packages/gitbook/src/app/(site)/(core)/~gitbook/ogimage/[pageId]/route.tsx index 9de958c31..1bf5e7dff 100644 --- a/packages/gitbook/src/app/(site)/(core)/~gitbook/ogimage/[pageId]/route.tsx +++ b/packages/gitbook/src/app/(site)/(core)/~gitbook/ogimage/[pageId]/route.tsx @@ -5,15 +5,31 @@ import { NextRequest } from 'next/server'; import colorContrast from 'postcss-color-contrast/js'; import React from 'react'; +import { googleFontsMap } from '@/fonts'; import { getGitBookContextFromHeaders } from '@/lib/gitbook-context'; import { getAbsoluteHref } from '@/lib/links'; -import { tcls } from '@/lib/tailwind'; +import { filterOutNullable } from '@/lib/typescript'; import { getContentTitle } from '@/lib/utils'; import { PageIdParams, fetchPageData } from '../../../../fetch'; export const runtime = 'edge'; +async function loadGoogleFont(font: string, text: string) { + const url = `https://fonts.googleapis.com/css2?family=${font}&text=${encodeURIComponent(text)}`; + const css = await (await fetch(url)).text(); + const resource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/); + + if (resource) { + const response = await fetch(resource[1]); + if (response.status == 200) { + return await response.arrayBuffer(); + } + } + + throw new Error('failed to load font data'); +} + /** * Render the OpenGraph image for a space. */ @@ -21,30 +37,60 @@ export async function GET(req: NextRequest, { params }: { params: Promise res.arrayBuffer()); - const interBold = await fetch( - new URL('../../../../../../fonts/Inter/Inter-Bold.ttf', import.meta.url), - ).then((res) => res.arrayBuffer()); + // Compute all text to load only the necessary fonts + const contentTitle = customization.header.logo + ? '' + : getContentTitle(space, customization, site ?? null); + const pageTitle = page + ? page.title.length > 64 + ? page.title.slice(0, 64) + '...' + : page.title + : 'Not found'; + const pageDescription = + page?.description && page?.title.length <= 64 + ? page.description.length > 164 + ? page.description.slice(0, 164) + '...' + : page.description + : ''; + + const fontFamily = googleFontsMap[customization.styling.font] ?? 'Inter'; + + const regularText = pageDescription; + const boldText = `${contentTitle}${pageTitle}`; + + const fonts = ( + await Promise.all([ + regularText + ? loadGoogleFont(`${fontFamily}:wght@400`, regularText).then((data) => ({ + name: fontFamily, + data, + style: 'normal' as const, + weight: 400 as const, + })) + : null, + boldText + ? loadGoogleFont(`${fontFamily}:wght@700`, `${contentTitle}${pageTitle}`).then( + (data) => ({ + name: fontFamily, + data, + style: 'normal' as const, + weight: 700 as const, + }), + ) + : null, + ]) + ).filter(filterOutNullable); const theme = customization.themes.default; const useLightTheme = theme === 'light'; // We have no access to CSS variables, so we'll have to hardcode some values - const baseColors = { - light: '#ffffff', - dark: '#111827', - }; + const baseColors = { light: '#ffffff', dark: '#111827' }; let colors = { background: baseColors[theme], @@ -92,49 +138,17 @@ export async function GET(req: NextRequest, { params }: { params: Promise { - if ('icon' in customization.favicon) - return ( - Icon - ); - if ('emoji' in customization.favicon) - return ( - - {String.fromCodePoint(parseInt('0x' + customization.favicon.emoji))} - - ); - const src = getAbsoluteHref( - ctx, - `~gitbook/icon?size=medium&theme=${customization.themes.default}`, - true, - ); - return Icon; - })(); - return new ImageResponse( (
{/* Gradient */}
{/* Grid */} - Grid + Grid {/* Logo */} {customization.header.logo ? ( @@ -160,39 +170,46 @@ export async function GET(req: NextRequest, { params }: { params: Promise ) : ( -
- {favicon} -

- {getContentTitle(space, customization, site ?? null)} -

+
+ {(() => { + if ('icon' in customization.favicon) + return ( + Icon + ); + if ('emoji' in customization.favicon) + return ( + + {String.fromCodePoint( + parseInt('0x' + customization.favicon.emoji), + )} + + ); + const src = getAbsoluteHref( + ctx, + `~gitbook/icon?size=medium&theme=${customization.themes.default}`, + true, + ); + return Icon; + })()} +

{contentTitle}

)} {/* Title and description */} -
+

- {page - ? page.title.length > 64 - ? page.title.slice(0, 64) + '...' - : page.title - : 'Not found'} + {pageTitle}

- {page?.description && page?.title.length <= 64 ? ( -

- {page.description.length > 164 - ? page.description.slice(0, 164) + '...' - : page.description} -

+ {pageDescription ? ( +

{pageDescription}

) : null}
@@ -200,20 +217,7 @@ export async function GET(req: NextRequest, { params }: { params: Promise Date: Fri, 10 Jan 2025 21:49:54 +0100 Subject: [PATCH 2/4] Fix padding of ads box (#2724) --- packages/gitbook/src/components/PageAside/PageAside.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gitbook/src/components/PageAside/PageAside.tsx b/packages/gitbook/src/components/PageAside/PageAside.tsx index 92d35264e..481c7730d 100644 --- a/packages/gitbook/src/components/PageAside/PageAside.tsx +++ b/packages/gitbook/src/components/PageAside/PageAside.tsx @@ -30,7 +30,7 @@ function getTopOffset(props: { sectionsHeader: boolean; topHeader: boolean }) { } if (props.topHeader) { - return 'lg:top-16 lg:max-h-[calc(100vh_-_3rem)]'; + return 'lg:top-16 lg:max-h-[calc(100vh_-_4rem)]'; } return 'lg:top-0 lg:max-h-screen'; @@ -237,7 +237,7 @@ export async function PageAside(props: { spaceId={space.id} siteAdsStatus={site?.ads && site.ads.status ? site.ads.status : undefined} ignore={process.env.NODE_ENV !== 'production'} - style={tcls(site?.ads && site.ads.status === SiteAdsStatus.Live && ['mt-4'])} + style={tcls(site?.ads && site.ads.status === SiteAdsStatus.Live && ['mb-4'])} /> ); From f584148ab938f00b4b791dabf579a628af6529ae Mon Sep 17 00:00:00 2001 From: Taran Vohra Date: Sun, 12 Jan 2025 12:57:38 +0530 Subject: [PATCH 3/4] temporarily add back cloudflare KV cache backend (#2726) --- packages/gitbook/src/lib/cache/backends.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/gitbook/src/lib/cache/backends.ts b/packages/gitbook/src/lib/cache/backends.ts index 20c54dc53..59379cfd2 100644 --- a/packages/gitbook/src/lib/cache/backends.ts +++ b/packages/gitbook/src/lib/cache/backends.ts @@ -1,5 +1,6 @@ import { cloudflareCache } from './cloudflare-cache'; import { cloudflareDOCache } from './cloudflare-do'; +import { cloudflareKVCache } from './cloudflare-kv'; import { memoryCache } from './memory'; export const cacheBackends = [ @@ -9,6 +10,8 @@ export const cacheBackends = [ // Cache local to the datacenter // It can't be purged globally but it's faster cloudflareCache, + // Cache global, but with slow replication + cloudflareKVCache, // Global cache with slower performances cloudflareDOCache, ]; From 528a05398c3257f56ce952e3f51d498d1c8d4847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Mon, 13 Jan 2025 11:04:14 +0100 Subject: [PATCH 4/4] Fix server actions stability (#2728) Co-authored-by: Steven Hall --- .changeset/perfect-laws-pay.md | 5 +++++ .github/workflows/ci.yaml | 1 + packages/gitbook/next.config.js | 1 + turbo.json | 3 ++- 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/perfect-laws-pay.md diff --git a/.changeset/perfect-laws-pay.md b/.changeset/perfect-laws-pay.md new file mode 100644 index 000000000..68754db95 --- /dev/null +++ b/.changeset/perfect-laws-pay.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Fix server actions stability leading to no results found sometimes on search diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1a84f872f..f25c1f5a2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -41,6 +41,7 @@ jobs: run: bun run build:cloudflare env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: ${{ secrets.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY }} SENTRY_ORG: ${{ vars.SENTRY_ORG }} SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} SENTRY_DSN: ${{ vars.SENTRY_DSN }} diff --git a/packages/gitbook/next.config.js b/packages/gitbook/next.config.js index e2a136fad..032f72b6b 100644 --- a/packages/gitbook/next.config.js +++ b/packages/gitbook/next.config.js @@ -10,6 +10,7 @@ module.exports = withSentryConfig( GITBOOK_ASSETS_PREFIX: process.env.GITBOOK_ASSETS_PREFIX, GITBOOK_ICONS_URL: process.env.GITBOOK_ICONS_URL, GITBOOK_ICONS_TOKEN: process.env.GITBOOK_ICONS_TOKEN, + NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY, }, webpack(config, { dev, webpack }) { diff --git a/turbo.json b/turbo.json index 687684328..bc3bdf90b 100644 --- a/turbo.json +++ b/turbo.json @@ -19,7 +19,8 @@ }, // Build the package for Cloudflare Pages "build:cloudflare": { - "dependsOn": ["^build", "generate"] + "dependsOn": ["^build", "generate"], + "env": ["NEXT_SERVER_ACTIONS_ENCRYPTION_KEY"] }, // Check the package for type errors "typecheck": {