From e8e979b6c03fcec50ba3ba2b2fa58b232a821693 Mon Sep 17 00:00:00 2001 From: Peter White <1788320+peterwhite@users.noreply.github.com> Date: Mon, 7 Sep 2026 16:07:40 +0200 Subject: [PATCH] Serve permanent site redirects (#4586) --- bun.lock | 4 ++-- package.json | 2 +- .../gitbook/src/components/SitePage/fetch.ts | 18 ++++++++++++++++-- packages/gitbook/src/lib/context.ts | 6 ++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/bun.lock b/bun.lock index 5978e4818..b48f12e68 100644 --- a/bun.lock +++ b/bun.lock @@ -354,7 +354,7 @@ }, "catalog": { "@base-ui/react": "^1.7.0", - "@gitbook/api": "0.199.0", + "@gitbook/api": "0.200.0", "@scalar/api-client-react": "^1.3.46", "@tsconfig/node20": "^20.1.6", "@tsconfig/strictest": "^2.0.6", @@ -726,7 +726,7 @@ "@fortawesome/fontawesome-svg-core": ["@fortawesome/fontawesome-svg-core@7.2.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.2.0" } }, "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q=="], - "@gitbook/api": ["@gitbook/api@0.199.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-yLxkSTXlGk7jbtThV2vpnTfqZTq6yLgMJt6jhDGqOmP0LsYAVYYtg8NPf2tXp37aF46m3Z0D908wfSQyu374cg=="], + "@gitbook/api": ["@gitbook/api@0.200.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-JgPosRwabDqw8FzTpSZdEWCUdwUxO2vIHJH9A8CXYXBmubjjj/Ft01qnzbL2T5q1CSLSQKe9PvW9t5V+R/8iJA=="], "@gitbook/browser-types": ["@gitbook/browser-types@workspace:packages/browser-types"], diff --git a/package.json b/package.json index ccac0c529..c46f42fe8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@tsconfig/strictest": "^2.0.6", "@tsconfig/node20": "^20.1.6", "@base-ui/react": "^1.7.0", - "@gitbook/api": "0.199.0", + "@gitbook/api": "0.200.0", "@scalar/api-client-react": "^1.3.46", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/packages/gitbook/src/components/SitePage/fetch.ts b/packages/gitbook/src/components/SitePage/fetch.ts index 2b3bf07ad..9da07f868 100644 --- a/packages/gitbook/src/components/SitePage/fetch.ts +++ b/packages/gitbook/src/components/SitePage/fetch.ts @@ -1,4 +1,4 @@ -import { redirect } from 'next/navigation'; +import { permanentRedirect, redirect } from 'next/navigation'; import { SITE_REDIRECT_SOURCE_PATH_MAX_LENGTH, @@ -89,7 +89,21 @@ async function resolvePage(context: GitBookSiteContext, params: PagePathParams | }) )); if (resolvedSiteRedirect) { - return redirect(linker.toLinkForContent(resolvedSiteRedirect.target)); + const destination = linker.toLinkForContent(resolvedSiteRedirect.target); + const isPublicLiveContext = + !shareKey && + !context.changeRequest && + !context.preview && + context.revisionId === context.space.revision && + !context.isLoggedInVisitor; + if ( + resolvedSiteRedirect.redirect?.permanent && + !resolvedSiteRedirect.redirect.draft && + isPublicLiveContext + ) { + return permanentRedirect(destination); + } + return redirect(destination); } } diff --git a/packages/gitbook/src/lib/context.ts b/packages/gitbook/src/lib/context.ts index 20a1917db..16dec245b 100644 --- a/packages/gitbook/src/lib/context.ts +++ b/packages/gitbook/src/lib/context.ts @@ -201,6 +201,9 @@ export type GitBookSiteContext = GitBookSpaceContext & { /** Whether the request included a visitor token. */ isLoggedInVisitor: boolean; + /** Whether the site is rendered from a preview URL. */ + preview: boolean; + /** Whether to display agent instructions in the markdown output. Defaults to true when undefined. */ displayAgentInstructions?: boolean; @@ -287,6 +290,7 @@ export async function fetchSiteContextByURLLookup( isFallback: data.isFallback ?? false, noIndexSearch: data.noIndexSearch ?? false, isLoggedInVisitor: data.isLoggedInVisitor ?? false, + preview: data.preview ?? false, displayAgentInstructions: data.displayAgentInstructions, isAiAgent: data.isAiAgent, }); @@ -310,6 +314,7 @@ export async function fetchSiteContextByIds( isFallback: boolean; noIndexSearch: boolean; isLoggedInVisitor: boolean; + preview: boolean; displayAgentInstructions?: boolean; isAiAgent?: boolean; } @@ -439,6 +444,7 @@ export async function fetchSiteContextByIds( isFallback: ids.isFallback, noIndexSearch: ids.noIndexSearch, isLoggedInVisitor: ids.isLoggedInVisitor, + preview: ids.preview, displayAgentInstructions: ids.displayAgentInstructions, isAiAgent: ids.isAiAgent, };