diff --git a/packages/gitbook-v2/src/lib/data/prefetch.ts b/packages/gitbook-v2/src/lib/data/prefetch.ts index 29e4b8f89..ac356a808 100644 --- a/packages/gitbook-v2/src/lib/data/prefetch.ts +++ b/packages/gitbook-v2/src/lib/data/prefetch.ts @@ -47,7 +47,7 @@ const cachedInitialDate = cache(() => Date.now()); /** * Fetches the page data matching the requested pathname and fallback to root page when page is not found. */ -async function getPageDataWithFallback(args: { +export async function getPageDataWithFallback(args: { context: GitBookSiteContext; pagePathParams: PagePathParams; }) { @@ -63,28 +63,35 @@ async function getPageDataWithFallback(args: { }; } +export async function getIcons(context: GitBookSiteContext): Promise< + { + url: string; + type: string; + media: string; + }[] +> { + return Promise.all([getIcon(context, 'light'), getIcon(context, 'dark')]).then((urls) => [ + { + url: urls[0], + type: 'image/png', + media: '(prefers-color-scheme: light)', + }, + { + url: urls[1], + type: 'image/png', + media: '(prefers-color-scheme: dark)', + }, + ]); +} + export const getPrefetchedDataFromLayoutParams = cache( (params: RouteLayoutParams): PrefetchedLayoutData => { const startingDate = cachedInitialDate(); const staticSiteContext = getStaticSiteContext(params).finally(() => { console.log(`Finished fetching static site context in ${Date.now() - startingDate}ms`); }); - const icons = Promise.all([ - staticSiteContext.then(({ context }) => getIcon(context, 'light')), - staticSiteContext.then(({ context }) => getIcon(context, 'dark')), - ]) - .then((urls) => [ - { - url: urls[0], - type: 'image/png', - media: '(prefers-color-scheme: light)', - }, - { - url: urls[1], - type: 'image/png', - media: '(prefers-color-scheme: dark)', - }, - ]) + const icons = staticSiteContext + .then(({ context }) => getIcons(context)) .finally(() => { console.log(`Finished fetching icons in ${Date.now() - startingDate}ms`); }); diff --git a/packages/gitbook/src/app/middleware/(site)/(content)/layout.tsx b/packages/gitbook/src/app/middleware/(site)/(content)/layout.tsx index 10db3a345..4fce1512c 100644 --- a/packages/gitbook/src/app/middleware/(site)/(content)/layout.tsx +++ b/packages/gitbook/src/app/middleware/(site)/(content)/layout.tsx @@ -11,6 +11,7 @@ import { getVisitorAuthClaims } from '@/lib/adaptive'; import { getSiteContentPointer } from '@/lib/pointer'; import { shouldTrackEvents } from '@/lib/tracking'; import { fetchV1ContextForSitePointer } from '@/lib/v1'; +import { getIcons } from '@v2/lib/data/prefetch'; export const runtime = 'edge'; export const dynamic = 'force-dynamic'; @@ -44,7 +45,14 @@ export async function generateViewport(): Promise { export async function generateMetadata(): Promise { const context = await fetchLayoutData(); - return generateSiteLayoutMetadata(context); + const icons = getIcons(context); + return generateSiteLayoutMetadata({ + staticSiteContext: Promise.resolve({ + context, + visitorAuthClaims: {}, + }), + icons, + }); } async function fetchLayoutData() { diff --git a/packages/gitbook/src/components/PageBody/PageBody.tsx b/packages/gitbook/src/components/PageBody/PageBody.tsx index 196ba3406..cbe9a0a93 100644 --- a/packages/gitbook/src/components/PageBody/PageBody.tsx +++ b/packages/gitbook/src/components/PageBody/PageBody.tsx @@ -27,7 +27,7 @@ export function PageBody(props: { page: RevisionPageDocument; ancestors: AncestorRevisionPage[]; document: JSONDocument | null; - prefetchedRef: Promise>>; + prefetchedRef?: Promise>>; withPageFeedback: boolean; }) { const { page, context, ancestors, document, withPageFeedback } = props; @@ -46,7 +46,7 @@ export function PageBody(props: { if (!ref) { return null; } - if (options) { + if (options || !props.prefetchedRef) { return resolveContentRef(ref, context, options); } return props.prefetchedRef.then((prefetched) => prefetched.get(ref) ?? null); diff --git a/packages/gitbook/src/components/SitePage/SitePage.tsx b/packages/gitbook/src/components/SitePage/SitePage.tsx index 66334fbaf..f6245c03e 100644 --- a/packages/gitbook/src/components/SitePage/SitePage.tsx +++ b/packages/gitbook/src/components/SitePage/SitePage.tsx @@ -10,27 +10,41 @@ import { getPagePath } from '@/lib/pages'; import { isPageIndexable, isSiteIndexable } from '@/lib/seo'; import type { RouteParams } from '@v2/app/utils'; -import { getPrefetchedDataFromPageParams } from '@v2/lib/data/prefetch'; +import { getPageDocument } from '@v2/lib/data/pages'; +import { getPageDataWithFallback, getPrefetchedDataFromPageParams } from '@v2/lib/data/prefetch'; import { getResizedImageURL } from '@v2/lib/images'; import { PageContextProvider } from '../PageContext'; import { PageClientLayout } from './PageClientLayout'; -import { getPathnameParam } from './fetch'; +import { type PagePathParams, getPathnameParam } from './fetch'; export type SitePageProps = { context: GitBookSiteContext; - pageParams: RouteParams; + /** + * `RouteParams` is used in V2, `PagePathParams` is used in V1. + */ + pageParams: RouteParams | PagePathParams; }; +function isV2(params: RouteParams | PagePathParams): params is RouteParams { + return 'pagePath' in params; +} + /** * Fetch and render a page. */ export async function SitePage(props: SitePageProps) { - console.log('Rendering site page', props.pageParams); - const prefetchedData = getPrefetchedDataFromPageParams(props.pageParams); - const { context, pageTarget } = await prefetchedData.pageData; + const prefetchedData = isV2(props.pageParams) + ? getPrefetchedDataFromPageParams(props.pageParams) + : null; + const { context, pageTarget } = prefetchedData + ? await prefetchedData.pageData + : await getPageDataWithFallback({ + context: props.context, + pagePathParams: props.pageParams as PagePathParams, + }); const rawPathname = getPathnameParam({ - pathname: props.pageParams.pagePath, + pathname: isV2(props.pageParams) ? props.pageParams.pagePath : props.pageParams.pathname, }); if (!pageTarget) { const pathname = rawPathname.toLowerCase(); @@ -65,7 +79,9 @@ export async function SitePage(props: SitePageProps) { const withSections = Boolean(sections && sections.list.length > 0); const headerOffset = { sectionsHeader: withSections, topHeader: withTopHeader }; - const document = await prefetchedData.document; + const document = prefetchedData + ? await prefetchedData.document + : await getPageDocument(context, page); return ( @@ -88,7 +104,7 @@ export async function SitePage(props: SitePageProps) { ancestors={ancestors} document={document} withPageFeedback={withPageFeedback} - prefetchedRef={prefetchedData.prefetchedRef} + prefetchedRef={prefetchedData ? prefetchedData.prefetchedRef : undefined} /> @@ -111,8 +127,12 @@ export async function generateSitePageViewport(context: GitBookSiteContext): Pro } export async function generateSitePageMetadata(props: SitePageProps): Promise { - const { context, pageTarget } = await getPrefetchedDataFromPageParams(props.pageParams) - .pageData; + const { context, pageTarget } = isV2(props.pageParams) + ? await getPrefetchedDataFromPageParams(props.pageParams).pageData + : await getPageDataWithFallback({ + context: props.context, + pagePathParams: props.pageParams as PagePathParams, + }); if (!pageTarget) { notFound();