From fab94f47c43bca2dfdc6ef608303173ff4da8de2 Mon Sep 17 00:00:00 2001 From: Nicolas Dorseuil Date: Wed, 8 Oct 2025 09:20:09 +0200 Subject: [PATCH] store customization in a cookie for preview route --- packages/gitbook/src/lib/visitors.ts | 1 + packages/gitbook/src/middleware.ts | 29 ++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/gitbook/src/lib/visitors.ts b/packages/gitbook/src/lib/visitors.ts index 89e96a0737..eb6c7cc79c 100644 --- a/packages/gitbook/src/lib/visitors.ts +++ b/packages/gitbook/src/lib/visitors.ts @@ -18,6 +18,7 @@ export type ResponseCookie = { sameSite: boolean | 'lax' | 'strict' | 'none' | undefined; secure: boolean; maxAge: number; + path: string; }>; }; diff --git a/packages/gitbook/src/middleware.ts b/packages/gitbook/src/middleware.ts index d4c7c4158e..c7c7e52e05 100644 --- a/packages/gitbook/src/middleware.ts +++ b/packages/gitbook/src/middleware.ts @@ -296,16 +296,41 @@ async function serveSiteRoutes(requestURL: URL, request: NextRequest) { requestHeaders.set(MiddlewareHeaders.SiteURLData, JSON.stringify(stableSiteURLData)); // Preview of customization/theme - const customization = siteRequestURL.searchParams.get('customization'); + const customizationCookie = request.cookies.get(MiddlewareHeaders.Customization); + const customization = + siteRequestURL.searchParams.get('customization') ?? + (customizationCookie ? decodeURIComponent(customizationCookie.value) : undefined); if (customization && validateSerializedCustomization(customization)) { routeType = 'dynamic'; // We need to encode the customization headers, otherwise it will fail for some customization values containing non ASCII chars on vercel. requestHeaders.set(MiddlewareHeaders.Customization, encodeURIComponent(customization)); + cookies.push({ + name: MiddlewareHeaders.Customization, + value: encodeURIComponent(customization), + options: { + httpOnly: true, + sameSite: 'lax', + maxAge: 10 * 60, // 10 minutes + path: '/url/preview', // Only send the cookie to preview routes + }, + }); } - const theme = siteRequestURL.searchParams.get('theme'); + const theme = + siteRequestURL.searchParams.get('theme') ?? + request.cookies.get(MiddlewareHeaders.Theme)?.value; if (theme === CustomizationThemeMode.Dark || theme === CustomizationThemeMode.Light) { routeType = 'dynamic'; requestHeaders.set(MiddlewareHeaders.Theme, theme); + cookies.push({ + name: MiddlewareHeaders.Theme, + value: theme, + options: { + httpOnly: true, + sameSite: 'lax', + maxAge: 10 * 60, // 10 minutes + path: '/url/preview', // Only send the cookie to preview routes + }, + }); } // We support forcing dynamic routes by setting a `gitbook-dynamic-route` cookie