diff --git a/packages/next/src/server/api-utils/node/api-resolver.ts b/packages/next/src/server/api-utils/node/api-resolver.ts index ced64c1dd5edf..3dbd152933410 100644 --- a/packages/next/src/server/api-utils/node/api-resolver.ts +++ b/packages/next/src/server/api-utils/node/api-resolver.ts @@ -42,6 +42,7 @@ type ApiContext = __ApiPreviewProps & { allowedRevalidateHeaderKeys?: string[] hostname?: string revalidate?: RevalidateFn + multiZoneDraftMode?: boolean } function getMaxContentLength(responseLimit?: ResponseLimit) { @@ -348,7 +349,7 @@ export async function apiResolver( apiReq.query = query // Parsing preview data setLazyProp({ req: apiReq }, 'previewData', () => - tryGetPreviewData(req, res, apiContext) + tryGetPreviewData(req, res, apiContext, !!apiContext.multiZoneDraftMode) ) // Checking if preview mode is enabled setLazyProp({ req: apiReq }, 'preview', () => diff --git a/packages/next/src/server/api-utils/node/try-get-preview-data.ts b/packages/next/src/server/api-utils/node/try-get-preview-data.ts index 6140bd2e9f3d5..f58fa88eb3946 100644 --- a/packages/next/src/server/api-utils/node/try-get-preview-data.ts +++ b/packages/next/src/server/api-utils/node/try-get-preview-data.ts @@ -17,7 +17,8 @@ import { HeadersAdapter } from '../../web/spec-extension/adapters/headers' export function tryGetPreviewData( req: IncomingMessage | BaseNextRequest | Request, res: ServerResponse | BaseNextResponse, - options: __ApiPreviewProps + options: __ApiPreviewProps, + multiZoneDraftMode: boolean ): PreviewData { // if an On-Demand revalidation is being done preview mode // is disabled @@ -61,13 +62,17 @@ export function tryGetPreviewData( // Case: one cookie is set, but not the other. if (!previewModeId || !tokenPreviewData) { - clearPreviewData(res as NextApiResponse) + if (!multiZoneDraftMode) { + clearPreviewData(res as NextApiResponse) + } return false } // Case: preview session is for an old build. if (previewModeId !== options.previewModeId) { - clearPreviewData(res as NextApiResponse) + if (!multiZoneDraftMode) { + clearPreviewData(res as NextApiResponse) + } return false } diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index fd078d9be91bb..5e24b14655de9 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2187,7 +2187,12 @@ export default abstract class Server< if (process.env.NEXT_RUNTIME !== 'edge') { const { tryGetPreviewData } = require('./api-utils/node/try-get-preview-data') as typeof import('./api-utils/node/try-get-preview-data') - previewData = tryGetPreviewData(req, res, this.renderOpts.previewProps) + previewData = tryGetPreviewData( + req, + res, + this.renderOpts.previewProps, + !!this.nextConfig.experimental.multiZoneDraftMode + ) isPreviewMode = previewData !== false } } @@ -2394,6 +2399,7 @@ export default abstract class Server< locale, locales, defaultLocale, + multiZoneDraftMode: this.nextConfig.experimental.multiZoneDraftMode, // For getServerSideProps and getInitialProps we need to ensure we use the original URL // and not the resolved URL to prevent a hydration mismatch on // asPath diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index fa1d3471763ae..69ba54f9e9b44 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -308,6 +308,7 @@ export const configSchema: zod.ZodType = z.lazy(() => linkNoTouchStart: z.boolean().optional(), manualClientBasePath: z.boolean().optional(), middlewarePrefetch: z.enum(['strict', 'flexible']).optional(), + multiZoneDraftMode: z.boolean().optional(), cssChunking: z.enum(['strict', 'loose']).optional(), nextScriptWorkers: z.boolean().optional(), // The critter option is unknown, use z.any() here diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index 66c04a1e3c7e9..ab1a82e73a26f 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -211,6 +211,7 @@ export interface LoggingConfig { } export interface ExperimentalConfig { + multiZoneDraftMode?: boolean appNavFailHandling?: boolean flyingShuttle?: { mode?: 'full' | 'store-only' } prerenderEarlyExit?: boolean @@ -979,6 +980,7 @@ export const defaultConfig: NextConfig = { modularizeImports: undefined, outputFileTracingRoot: process.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT || '', experimental: { + multiZoneDraftMode: false, appNavFailHandling: Boolean(process.env.NEXT_PRIVATE_FLYING_SHUTTLE), flyingShuttle: Boolean(process.env.NEXT_PRIVATE_FLYING_SHUTTLE) ? { diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts index 5e9fc519c2fc6..06829ef0eeaa2 100644 --- a/packages/next/src/server/load-components.ts +++ b/packages/next/src/server/load-components.ts @@ -67,6 +67,7 @@ export type LoadComponentsReturnType = { routeModule: RouteModule isAppPath?: boolean page: string + multiZoneDraftMode?: boolean } /** diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index ae7671ac4afc5..916e7c3c5c78a 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -532,6 +532,7 @@ export default class NextNodeServer extends BaseServer< params: match.params, page: match.definition.pathname, onError: this.instrumentationOnRequestError.bind(this), + multiZoneDraftMode: this.nextConfig.experimental.multiZoneDraftMode, }) return true diff --git a/packages/next/src/server/render.tsx b/packages/next/src/server/render.tsx index 810998ca61fb4..139b51b4f4ad9 100644 --- a/packages/next/src/server/render.tsx +++ b/packages/next/src/server/render.tsx @@ -640,7 +640,12 @@ export async function renderToHTMLImpl( // Reads of this are cached on the `req` object, so this should resolve // instantly. There's no need to pass this data down from a previous // invoke. - previewData = tryGetPreviewData(req, res, previewProps) + previewData = tryGetPreviewData( + req, + res, + previewProps, + !!renderOpts.multiZoneDraftMode + ) isPreview = previewData !== false } diff --git a/packages/next/src/server/route-modules/pages-api/module.ts b/packages/next/src/server/route-modules/pages-api/module.ts index 6eacf264488ff..6cdd142bea452 100644 --- a/packages/next/src/server/route-modules/pages-api/module.ts +++ b/packages/next/src/server/route-modules/pages-api/module.ts @@ -97,6 +97,11 @@ type PagesAPIRouteHandlerContext = RouteModuleHandleContext & { * The error handler for the request. */ onError?: Parameters[8] + + /** + * whether multi-zone flag is enabled for draft mode + */ + multiZoneDraftMode?: boolean } export type PagesAPIRouteModuleOptions = RouteModuleOptions< @@ -148,6 +153,7 @@ export class PagesAPIRouteModule extends RouteModule< trustHostHeader: context.trustHostHeader, allowedRevalidateHeaderKeys: context.allowedRevalidateHeaderKeys, hostname: context.hostname, + multiZoneDraftMode: context.multiZoneDraftMode, }, context.minimalMode, context.dev,