From 5ecf746b6451ee77718e623df1128eac161ab0f8 Mon Sep 17 00:00:00 2001 From: Nolann Biron Date: Thu, 10 Sep 2026 12:25:18 +0200 Subject: [PATCH] Request insights and visitor endpoints relative to the served origin --- .changeset/relative-insights-visitor-urls.md | 5 +++++ .../components/SpaceLayout/SpaceLayout.tsx | 18 +++++++-------- packages/gitbook/tests/insights.test.ts | 22 +++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 .changeset/relative-insights-visitor-urls.md create mode 100644 packages/gitbook/tests/insights.test.ts diff --git a/.changeset/relative-insights-visitor-urls.md b/.changeset/relative-insights-visitor-urls.md new file mode 100644 index 000000000..fe848a113 --- /dev/null +++ b/.changeset/relative-insights-visitor-urls.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix analytics and adaptive content silently breaking on sites served from a different host than the one configured (apex vs www, domain alias, CDN). The insights and visitor-claims endpoints are now requested relative to the page's own origin instead of the configured host, which a prerendered page cannot know. diff --git a/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx b/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx index df6b60f32..0a1f6a30d 100644 --- a/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx +++ b/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx @@ -58,15 +58,15 @@ export function SpaceLayoutServerContext(props: SpaceLayoutProps) { ? context.linker.toPathInSite('~gitbook/auth/login') : null; - const eventUrl = new URL( - context.linker.toAbsoluteURL(context.linker.toPathInSite('/~gitbook/__evt')) - ); - eventUrl.searchParams.set('o', context.organizationId); - eventUrl.searchParams.set('s', context.site.id); + // Kept relative: a prerendered page has no request to read the host from, so an absolute URL + // pins the configured host and turns these fetches cross-origin when it differs (apex vs www). + const eventParams = new URLSearchParams({ + o: context.organizationId, + s: context.site.id, + }); + const eventUrl = `${context.linker.toPathInSite('/~gitbook/__evt')}?${eventParams}`; - const getVisitorClaimsUrl = context.linker.toAbsoluteURL( - context.linker.toPathInSite('/~gitbook/visitor') - ); + const getVisitorClaimsUrl = context.linker.toPathInSite('/~gitbook/visitor'); return ( - + { + // The harness serves the site from BASE_URL while it is configured on gitbook.gitbook.io, + // reproducing the split (apex vs www, alias, CDN) that turns an absolute URL cross-origin. + const TEST_URL = getContentTestURL('https://gitbook.gitbook.io/test-gitbook-open'); + + it.each(['__evt', 'visitor'])( + 'should reference ~gitbook/%s relative to the served origin', + async (endpoint) => { + const response = await fetch(TEST_URL); + expect(response.status).toBe(200); + + const html = await response.text(); + + expect(html).toContain(`~gitbook/${endpoint}`); + expect(html).not.toMatch(new RegExp(`https?://[^"'\\\\\\s]*~gitbook/${endpoint}`)); + } + ); +});