{"version":3,"sources":["../../../src/server/app-render/app-render.tsx"],"sourcesContent":["import type {\n ActionResult,\n DynamicParamTypesShort,\n FlightRouterState,\n RenderOpts,\n Segment,\n CacheNodeSeedData,\n PreloadCallbacks,\n RSCPayload,\n FlightData,\n InitialRSCPayload,\n FlightDataPath,\n} from './types'\nimport {\n workAsyncStorage,\n type WorkStore,\n} from '../app-render/work-async-storage.external'\nimport type {\n PrerenderStoreModernRuntime,\n RequestStore,\n} from '../app-render/work-unit-async-storage.external'\nimport type { NextParsedUrlQuery } from '../request-meta'\nimport type { LoaderTree } from '../lib/app-dir-module'\nimport type { AppPageModule } from '../route-modules/app-page/module'\nimport type {\n ClientReferenceManifest,\n ManifestNode,\n} from '../../build/webpack/plugins/flight-manifest-plugin'\nimport type { DeepReadonly } from '../../shared/lib/deep-readonly'\nimport type { BaseNextRequest, BaseNextResponse } from '../base-http'\nimport type { IncomingHttpHeaders } from 'http'\n\nimport React, { type ErrorInfo, type JSX } from 'react'\n\nimport RenderResult, {\n type AppPageRenderResultMetadata,\n type RenderResultOptions,\n} from '../render-result'\nimport {\n chainStreams,\n renderToInitialFizzStream,\n createDocumentClosingStream,\n continueFizzStream,\n continueDynamicPrerender,\n continueStaticPrerender,\n continueDynamicHTMLResume,\n streamToBuffer,\n streamToString,\n} from '../stream-utils/node-web-streams-helper'\nimport { stripInternalQueries } from '../internal-utils'\nimport {\n NEXT_HMR_REFRESH_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_ROUTER_STALE_TIME_HEADER,\n NEXT_URL,\n RSC_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_HMR_REFRESH_HASH_COOKIE,\n NEXT_DID_POSTPONE_HEADER,\n} from '../../client/components/app-router-headers'\nimport { createMetadataContext } from '../../lib/metadata/metadata-context'\nimport { createRequestStoreForRender } from '../async-storage/request-store'\nimport { createWorkStore } from '../async-storage/work-store'\nimport {\n getAccessFallbackErrorTypeByStatus,\n getAccessFallbackHTTPStatus,\n isHTTPAccessFallbackError,\n} from '../../client/components/http-access-fallback/http-access-fallback'\nimport {\n getURLFromRedirectError,\n getRedirectStatusCodeFromError,\n} from '../../client/components/redirect'\nimport { isRedirectError } from '../../client/components/redirect-error'\nimport { getImplicitTags, type ImplicitTags } from '../lib/implicit-tags'\nimport { AppRenderSpan, NextNodeServerSpan } from '../lib/trace/constants'\nimport { getTracer } from '../lib/trace/tracer'\nimport { FlightRenderResult } from './flight-render-result'\nimport {\n createFlightReactServerErrorHandler,\n createHTMLReactServerErrorHandler,\n createHTMLErrorHandler,\n type DigestedError,\n isUserLandError,\n getDigestForWellKnownError,\n} from './create-error-handler'\nimport { dynamicParamTypes } from './get-short-dynamic-param-type'\nimport { getSegmentParam } from './get-segment-param'\nimport { getScriptNonceFromHeader } from './get-script-nonce-from-header'\nimport { parseAndValidateFlightRouterState } from './parse-and-validate-flight-router-state'\nimport { createFlightRouterStateFromLoaderTree } from './create-flight-router-state-from-loader-tree'\nimport { handleAction } from './action-handler'\nimport { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr'\nimport { warn, error } from '../../build/output/log'\nimport { appendMutableCookies } from '../web/spec-extension/adapters/request-cookies'\nimport { createServerInsertedHTML } from './server-inserted-html'\nimport { getRequiredScripts } from './required-scripts'\nimport { addPathPrefix } from '../../shared/lib/router/utils/add-path-prefix'\nimport { makeGetServerInsertedHTML } from './make-get-server-inserted-html'\nimport { walkTreeWithFlightRouterState } from './walk-tree-with-flight-router-state'\nimport { createComponentTree, getRootParams } from './create-component-tree'\nimport { getAssetQueryString } from './get-asset-query-string'\nimport {\n getServerModuleMap,\n setReferenceManifestsSingleton,\n} from './encryption-utils'\nimport {\n DynamicState,\n type PostponedState,\n DynamicHTMLPreludeState,\n parsePostponedState,\n} from './postponed-state'\nimport {\n getDynamicDataPostponedState,\n getDynamicHTMLPostponedState,\n getPostponedFromState,\n} from './postponed-state'\nimport { isDynamicServerError } from '../../client/components/hooks-server-context'\nimport {\n useFlightStream,\n createInlinedDataReadableStream,\n} from './use-flight-response'\nimport {\n StaticGenBailoutError,\n isStaticGenBailoutError,\n} from '../../client/components/static-generation-bailout'\nimport { getStackWithoutErrorMessage } from '../../lib/format-server-error'\nimport {\n accessedDynamicData,\n createRenderInBrowserAbortSignal,\n formatDynamicAPIAccesses,\n isPrerenderInterruptedError,\n createDynamicTrackingState,\n createDynamicValidationState,\n trackAllowedDynamicAccess,\n throwIfDisallowedDynamic,\n PreludeState,\n consumeDynamicAccess,\n type DynamicAccess,\n logDisallowedDynamicError,\n warnOnSyncDynamicError,\n} from './dynamic-rendering'\nimport {\n getClientComponentLoaderMetrics,\n wrapClientComponentLoader,\n} from '../client-component-renderer-logger'\nimport { createServerModuleMap } from './action-utils'\nimport { isNodeNextRequest } from '../base-http/helpers'\nimport { parseRelativeUrl } from '../../shared/lib/router/utils/parse-relative-url'\nimport AppRouter from '../../client/components/app-router'\nimport type { ServerComponentsHmrCache } from '../response-cache'\nimport type { RequestErrorContext } from '../instrumentation/types'\nimport { getIsPossibleServerAction } from '../lib/server-action-request-meta'\nimport { createInitialRouterState } from '../../client/components/router-reducer/create-initial-router-state'\nimport { createMutableActionQueue } from '../../client/components/app-router-instance'\nimport { getRevalidateReason } from '../instrumentation/utils'\nimport { PAGE_SEGMENT_KEY } from '../../shared/lib/segment'\nimport type { FallbackRouteParams } from '../request/fallback-params'\nimport {\n prerenderAndAbortInSequentialTasksWithStages,\n processPrelude,\n} from './app-render-prerender-utils'\nimport {\n type ReactServerPrerenderResult,\n ReactServerResult,\n createReactServerPrerenderResult,\n createReactServerPrerenderResultFromRender,\n prerenderAndAbortInSequentialTasks,\n} from './app-render-prerender-utils'\nimport { printDebugThrownValueForProspectiveRender } from './prospective-render-utils'\nimport { scheduleInSequentialTasks } from './app-render-render-utils'\nimport { waitAtLeastOneReactRenderTask } from '../../lib/scheduler'\nimport {\n workUnitAsyncStorage,\n type PrerenderStore,\n} from './work-unit-async-storage.external'\nimport { CacheSignal } from './cache-signal'\nimport { getTracedMetadata } from '../lib/trace/utils'\nimport { InvariantError } from '../../shared/lib/invariant-error'\n\nimport { HTML_CONTENT_TYPE_HEADER, INFINITE_CACHE } from '../../lib/constants'\nimport { createComponentStylesAndScripts } from './create-component-styles-and-scripts'\nimport { parseLoaderTree } from './parse-loader-tree'\nimport {\n createPrerenderResumeDataCache,\n createRenderResumeDataCache,\n type PrerenderResumeDataCache,\n type RenderResumeDataCache,\n} from '../resume-data-cache/resume-data-cache'\nimport type { MetadataErrorType } from '../../lib/metadata/resolve-metadata'\nimport isError from '../../lib/is-error'\nimport { createServerInsertedMetadata } from './metadata-insertion/create-server-inserted-metadata'\nimport { getPreviouslyRevalidatedTags } from '../server-utils'\nimport { executeRevalidates } from '../revalidation-utils'\nimport {\n trackPendingChunkLoad,\n trackPendingImport,\n trackPendingModules,\n} from './module-loading/track-module-loading.external'\nimport { isReactLargeShellError } from './react-large-shell-error'\nimport type { GlobalErrorComponent } from '../../client/components/builtin/global-error'\nimport { normalizeConventionFilePath } from './segment-explorer-path'\nimport { getRequestMeta } from '../request-meta'\nimport { getDynamicParam } from '../../shared/lib/router/utils/get-dynamic-param'\nimport type { ExperimentalConfig } from '../config-shared'\nimport type { Params } from '../request/params'\nimport { createPromiseWithResolvers } from '../../shared/lib/promise-with-resolvers'\n\nexport type GetDynamicParamFromSegment = (\n // [slug] / [[slug]] / [...slug]\n segment: string\n) => DynamicParam | null\n\nexport type DynamicParam = {\n param: string\n value: string | string[] | null\n treeSegment: Segment\n type: DynamicParamTypesShort\n}\n\nexport type GenerateFlight = typeof generateDynamicFlightRenderResult\n\nexport type AppSharedContext = {\n buildId: string\n}\n\nexport type AppRenderContext = {\n sharedContext: AppSharedContext\n workStore: WorkStore\n url: ReturnType\n componentMod: AppPageModule\n renderOpts: RenderOpts\n parsedRequestHeaders: ParsedRequestHeaders\n getDynamicParamFromSegment: GetDynamicParamFromSegment\n query: NextParsedUrlQuery\n isPrefetch: boolean\n isPossibleServerAction: boolean\n requestTimestamp: number\n appUsingSizeAdjustment: boolean\n flightRouterState?: FlightRouterState\n requestId: string\n pagePath: string\n clientReferenceManifest: DeepReadonly\n assetPrefix: string\n isNotFoundPath: boolean\n nonce: string | undefined\n res: BaseNextResponse\n /**\n * For now, the implicit tags are common for the whole route. If we ever start\n * rendering/revalidating segments independently, they need to move to the\n * work unit store.\n */\n implicitTags: ImplicitTags\n}\n\ninterface ParseRequestHeadersOptions {\n readonly isDevWarmup: undefined | boolean\n readonly isRoutePPREnabled: boolean\n readonly previewModeId: string | undefined\n}\n\nconst flightDataPathHeadKey = 'h'\nconst getFlightViewportKey = (requestId: string) => requestId + 'v'\nconst getFlightMetadataKey = (requestId: string) => requestId + 'm'\n\nconst filterStackFrame =\n process.env.NODE_ENV !== 'production'\n ? (require('../lib/source-maps') as typeof import('../lib/source-maps'))\n .filterStackFrameDEV\n : undefined\n\ninterface ParsedRequestHeaders {\n /**\n * Router state provided from the client-side router. Used to handle rendering\n * from the common layout down. This value will be undefined if the request is\n * not a client-side navigation request, or if the request is a prefetch\n * request.\n */\n readonly flightRouterState: FlightRouterState | undefined\n readonly isPrefetchRequest: boolean\n readonly isRuntimePrefetchRequest: boolean\n readonly isRouteTreePrefetchRequest: boolean\n readonly isDevWarmupRequest: boolean\n readonly isHmrRefresh: boolean\n readonly isRSCRequest: boolean\n readonly nonce: string | undefined\n readonly previouslyRevalidatedTags: string[]\n}\n\nfunction parseRequestHeaders(\n headers: IncomingHttpHeaders,\n options: ParseRequestHeadersOptions\n): ParsedRequestHeaders {\n const isDevWarmupRequest = options.isDevWarmup === true\n\n // dev warmup requests are treated as prefetch RSC requests\n // runtime prefetch requests are *not* treated as prefetch requests\n // (TODO: this is confusing, we should refactor this to express this better)\n const isPrefetchRequest =\n isDevWarmupRequest || headers[NEXT_ROUTER_PREFETCH_HEADER] === '1'\n\n const isRuntimePrefetchRequest = headers[NEXT_ROUTER_PREFETCH_HEADER] === '2'\n\n const isHmrRefresh = headers[NEXT_HMR_REFRESH_HEADER] !== undefined\n\n // dev warmup requests are treated as prefetch RSC requests\n const isRSCRequest = isDevWarmupRequest || headers[RSC_HEADER] !== undefined\n\n const shouldProvideFlightRouterState =\n isRSCRequest && (!isPrefetchRequest || !options.isRoutePPREnabled)\n\n const flightRouterState = shouldProvideFlightRouterState\n ? parseAndValidateFlightRouterState(headers[NEXT_ROUTER_STATE_TREE_HEADER])\n : undefined\n\n // Checks if this is a prefetch of the Route Tree by the Segment Cache\n const isRouteTreePrefetchRequest =\n headers[NEXT_ROUTER_SEGMENT_PREFETCH_HEADER] === '/_tree'\n\n const csp =\n headers['content-security-policy'] ||\n headers['content-security-policy-report-only']\n\n const nonce =\n typeof csp === 'string' ? getScriptNonceFromHeader(csp) : undefined\n\n const previouslyRevalidatedTags = getPreviouslyRevalidatedTags(\n headers,\n options.previewModeId\n )\n\n return {\n flightRouterState,\n isPrefetchRequest,\n isRuntimePrefetchRequest,\n isRouteTreePrefetchRequest,\n isHmrRefresh,\n isRSCRequest,\n isDevWarmupRequest,\n nonce,\n previouslyRevalidatedTags,\n }\n}\n\nfunction createNotFoundLoaderTree(loaderTree: LoaderTree): LoaderTree {\n const components = loaderTree[2]\n const hasGlobalNotFound = !!components['global-not-found']\n return [\n '',\n {\n children: [\n PAGE_SEGMENT_KEY,\n {},\n {\n page: components['global-not-found'] ?? components['not-found'],\n },\n ],\n },\n // When global-not-found is present, skip layout from components\n hasGlobalNotFound ? components : {},\n ]\n}\n\n/**\n * Returns a function that parses the dynamic segment and return the associated value.\n */\nfunction makeGetDynamicParamFromSegment(\n params: { [key: string]: any },\n pagePath: string,\n fallbackRouteParams: FallbackRouteParams | null\n): GetDynamicParamFromSegment {\n return function getDynamicParamFromSegment(\n // [slug] / [[slug]] / [...slug]\n segment: string\n ) {\n const segmentParam = getSegmentParam(segment)\n if (!segmentParam) {\n return null\n }\n const segmentKey = segmentParam.param\n const dynamicParamType = dynamicParamTypes[segmentParam.type]\n return getDynamicParam(\n params,\n segmentKey,\n dynamicParamType,\n pagePath,\n fallbackRouteParams\n )\n }\n}\n\nfunction NonIndex({\n pagePath,\n statusCode,\n isPossibleServerAction,\n}: {\n pagePath: string\n statusCode: number | undefined\n isPossibleServerAction: boolean\n}) {\n const is404Page = pagePath === '/404'\n const isInvalidStatusCode = typeof statusCode === 'number' && statusCode > 400\n\n // Only render noindex for page request, skip for server actions\n // TODO: is this correct if `isPossibleServerAction` is a false positive?\n if (!isPossibleServerAction && (is404Page || isInvalidStatusCode)) {\n return \n }\n return null\n}\n\n/**\n * This is used by server actions & client-side navigations to generate RSC data from a client-side request.\n * This function is only called on \"dynamic\" requests (ie, there wasn't already a static response).\n * It uses request headers (namely `next-router-state-tree`) to determine where to start rendering.\n */\nasync function generateDynamicRSCPayload(\n ctx: AppRenderContext,\n options?: {\n actionResult: ActionResult\n skipFlight: boolean\n }\n): Promise {\n // Flight data that is going to be passed to the browser.\n // Currently a single item array but in the future multiple patches might be combined in a single request.\n\n // We initialize `flightData` to an empty string because the client router knows how to tolerate\n // it (treating it as an MPA navigation). The only time this function wouldn't generate flight data\n // is for server actions, if the server action handler instructs this function to skip it. When the server\n // action reducer sees a falsy value, it'll simply resolve the action with no data.\n let flightData: FlightData = ''\n\n const {\n componentMod: {\n tree: loaderTree,\n createMetadataComponents,\n MetadataBoundary,\n ViewportBoundary,\n },\n getDynamicParamFromSegment,\n appUsingSizeAdjustment,\n query,\n requestId,\n flightRouterState,\n workStore,\n url,\n } = ctx\n\n const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata\n\n if (!options?.skipFlight) {\n const preloadCallbacks: PreloadCallbacks = []\n\n const {\n ViewportTree,\n MetadataTree,\n getViewportReady,\n getMetadataReady,\n StreamingMetadataOutlet,\n } = createMetadataComponents({\n tree: loaderTree,\n parsedQuery: query,\n pathname: url.pathname,\n metadataContext: createMetadataContext(ctx.renderOpts),\n getDynamicParamFromSegment,\n appUsingSizeAdjustment,\n workStore,\n MetadataBoundary,\n ViewportBoundary,\n serveStreamingMetadata,\n })\n\n flightData = (\n await walkTreeWithFlightRouterState({\n ctx,\n loaderTreeToFilter: loaderTree,\n parentParams: {},\n flightRouterState,\n // For flight, render metadata inside leaf page\n rscHead: (\n \n {/* noindex needs to be blocking */}\n \n {/* Adding requestId as react key to make metadata remount for each render */}\n \n \n \n ),\n injectedCSS: new Set(),\n injectedJS: new Set(),\n injectedFontPreloadTags: new Set(),\n rootLayoutIncluded: false,\n getViewportReady,\n getMetadataReady,\n preloadCallbacks,\n StreamingMetadataOutlet,\n })\n ).map((path) => path.slice(1)) // remove the '' (root) segment\n }\n\n // If we have an action result, then this is a server action response.\n // We can rely on this because `ActionResult` will always be a promise, even if\n // the result is falsey.\n if (options?.actionResult) {\n return {\n a: options.actionResult,\n f: flightData,\n b: ctx.sharedContext.buildId,\n }\n }\n\n // Otherwise, it's a regular RSC response.\n return {\n b: ctx.sharedContext.buildId,\n f: flightData,\n S: workStore.isStaticGeneration,\n }\n}\n\nfunction createErrorContext(\n ctx: AppRenderContext,\n renderSource: RequestErrorContext['renderSource']\n): RequestErrorContext {\n return {\n routerKind: 'App Router',\n routePath: ctx.pagePath,\n // TODO: is this correct if `isPossibleServerAction` is a false positive?\n routeType: ctx.isPossibleServerAction ? 'action' : 'render',\n renderSource,\n revalidateReason: getRevalidateReason(ctx.workStore),\n }\n}\n\n/**\n * Produces a RenderResult containing the Flight data for the given request. See\n * `generateDynamicRSCPayload` for information on the contents of the render result.\n */\nasync function generateDynamicFlightRenderResult(\n req: BaseNextRequest,\n ctx: AppRenderContext,\n requestStore: RequestStore,\n options?: {\n actionResult: ActionResult\n skipFlight: boolean\n componentTree?: CacheNodeSeedData\n preloadCallbacks?: PreloadCallbacks\n temporaryReferences?: WeakMap\n }\n): Promise {\n const renderOpts = ctx.renderOpts\n\n function onFlightDataRenderError(err: DigestedError) {\n return renderOpts.onInstrumentationRequestError?.(\n err,\n req,\n createErrorContext(ctx, 'react-server-components-payload')\n )\n }\n const onError = createFlightReactServerErrorHandler(\n !!renderOpts.dev,\n onFlightDataRenderError\n )\n\n const RSCPayload: RSCPayload & {\n /** Only available during cacheComponents development builds. Used for logging errors. */\n _validation?: Promise\n } = await workUnitAsyncStorage.run(\n requestStore,\n generateDynamicRSCPayload,\n ctx,\n options\n )\n\n // For app dir, use the bundled version of Flight server renderer (renderToReadableStream)\n // which contains the subset React.\n const flightReadableStream = workUnitAsyncStorage.run(\n requestStore,\n ctx.componentMod.renderToReadableStream,\n RSCPayload,\n ctx.clientReferenceManifest.clientModules,\n {\n onError,\n temporaryReferences: options?.temporaryReferences,\n filterStackFrame,\n }\n )\n\n return new FlightRenderResult(flightReadableStream, {\n fetchMetrics: ctx.workStore.fetchMetrics,\n })\n}\n\nasync function generateRuntimePrefetchResult(\n req: BaseNextRequest,\n res: BaseNextResponse,\n ctx: AppRenderContext,\n requestStore: RequestStore\n): Promise {\n const { workStore } = ctx\n const renderOpts = ctx.renderOpts\n\n function onFlightDataRenderError(err: DigestedError) {\n return renderOpts.onInstrumentationRequestError?.(\n err,\n req,\n // TODO(runtime-ppr): should we use a different value?\n createErrorContext(ctx, 'react-server-components-payload')\n )\n }\n const onError = createFlightReactServerErrorHandler(\n false,\n onFlightDataRenderError\n )\n\n const metadata: AppPageRenderResultMetadata = {}\n\n const generatePayload = () => generateDynamicRSCPayload(ctx, undefined)\n\n const {\n componentMod: { tree },\n getDynamicParamFromSegment,\n } = ctx\n const rootParams = getRootParams(tree, getDynamicParamFromSegment)\n\n // We need to share caches between the prospective prerender and the final prerender,\n // but we're not going to persist this anywhere.\n const prerenderResumeDataCache = createPrerenderResumeDataCache()\n // We're not resuming an existing render.\n const renderResumeDataCache = null\n\n await prospectiveRuntimeServerPrerender(\n ctx,\n generatePayload,\n prerenderResumeDataCache,\n renderResumeDataCache,\n rootParams,\n requestStore.cookies,\n requestStore.draftMode\n )\n\n const response = await finalRuntimeServerPrerender(\n ctx,\n generatePayload,\n prerenderResumeDataCache,\n renderResumeDataCache,\n rootParams,\n requestStore.cookies,\n requestStore.draftMode,\n onError\n )\n\n applyMetadataFromPrerenderResult(response, metadata, workStore)\n metadata.fetchMetrics = ctx.workStore.fetchMetrics\n\n if (response.isPartial) {\n res.setHeader(NEXT_DID_POSTPONE_HEADER, '1')\n }\n\n return new FlightRenderResult(response.result.prelude, metadata)\n}\n\nasync function prospectiveRuntimeServerPrerender(\n ctx: AppRenderContext,\n getPayload: () => any,\n prerenderResumeDataCache: PrerenderResumeDataCache | null,\n renderResumeDataCache: RenderResumeDataCache | null,\n rootParams: Params,\n cookies: PrerenderStoreModernRuntime['cookies'],\n draftMode: PrerenderStoreModernRuntime['draftMode']\n) {\n const { implicitTags, renderOpts, workStore } = ctx\n\n const { clientReferenceManifest, ComponentMod } = renderOpts\n\n assertClientReferenceManifest(clientReferenceManifest)\n\n // Prerender controller represents the lifetime of the prerender.\n // It will be aborted when a Task is complete or a synchronously aborting\n // API is called. Notably during cache-filling renders this does not actually\n // terminate the render itself which will continue until all caches are filled\n const initialServerPrerenderController = new AbortController()\n\n // This controller represents the lifetime of the React render call. Notably\n // during the cache-filling render it is different from the prerender controller\n // because we don't want to end the react render until all caches are filled.\n const initialServerRenderController = new AbortController()\n\n // The cacheSignal helps us track whether caches are still filling or we are ready\n // to cut the render off.\n const cacheSignal = new CacheSignal()\n\n const initialServerPrerenderStore: PrerenderStoreModernRuntime = {\n type: 'prerender-runtime',\n phase: 'render',\n rootParams,\n implicitTags,\n renderSignal: initialServerRenderController.signal,\n controller: initialServerPrerenderController,\n // During the initial prerender we need to track all cache reads to ensure\n // we render long enough to fill every cache it is possible to visit during\n // the final prerender.\n cacheSignal,\n // We only need to track dynamic accesses during the final prerender.\n dynamicTracking: null,\n // Runtime prefetches are never cached server-side, only client-side,\n // so we set `expire` and `revalidate` to their minimum values just in case.\n revalidate: 1,\n expire: 0,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n renderResumeDataCache,\n prerenderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined,\n // We only need task sequencing in the final prerender.\n runtimeStagePromise: null,\n // These are not present in regular prerenders, but allowed in a runtime prerender.\n cookies,\n draftMode,\n }\n\n // We're not going to use the result of this render because the only time it could be used\n // is if it completes in a microtask and that's likely very rare for any non-trivial app\n const initialServerPayload = await workUnitAsyncStorage.run(\n initialServerPrerenderStore,\n getPayload\n )\n\n const pendingInitialServerResult = workUnitAsyncStorage.run(\n initialServerPrerenderStore,\n ComponentMod.prerender,\n initialServerPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: (err) => {\n const digest = getDigestForWellKnownError(err)\n\n if (digest) {\n return digest\n }\n\n if (initialServerPrerenderController.signal.aborted) {\n // The render aborted before this error was handled which indicates\n // the error is caused by unfinished components within the render\n return\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n },\n // we don't care to track postpones during the prospective render because we need\n // to always do a final render anyway\n onPostpone: undefined,\n // We don't want to stop rendering until the cacheSignal is complete so we pass\n // a different signal to this render call than is used by dynamic APIs to signify\n // transitioning out of the prerender environment\n signal: initialServerRenderController.signal,\n }\n )\n\n // Wait for all caches to be finished filling and for async imports to resolve\n trackPendingModules(cacheSignal)\n await cacheSignal.cacheReady()\n\n initialServerRenderController.abort()\n initialServerPrerenderController.abort()\n\n // We don't need to continue the prerender process if we already\n // detected invalid dynamic usage in the initial prerender phase.\n if (workStore.invalidDynamicUsageError) {\n throw workStore.invalidDynamicUsageError\n }\n\n try {\n return await createReactServerPrerenderResult(pendingInitialServerResult)\n } catch (err) {\n if (\n initialServerRenderController.signal.aborted ||\n initialServerPrerenderController.signal.aborted\n ) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n return null\n }\n}\n\nasync function finalRuntimeServerPrerender(\n ctx: AppRenderContext,\n getPayload: () => any,\n prerenderResumeDataCache: PrerenderResumeDataCache | null,\n renderResumeDataCache: RenderResumeDataCache | null,\n rootParams: Params,\n cookies: PrerenderStoreModernRuntime['cookies'],\n draftMode: PrerenderStoreModernRuntime['draftMode'],\n onError: (err: unknown) => string | undefined\n) {\n const { implicitTags, renderOpts } = ctx\n\n const {\n clientReferenceManifest,\n ComponentMod,\n experimental,\n isDebugDynamicAccesses,\n } = renderOpts\n\n assertClientReferenceManifest(clientReferenceManifest)\n\n const selectStaleTime = createSelectStaleTime(experimental)\n\n let serverIsDynamic = false\n const finalServerController = new AbortController()\n\n const serverDynamicTracking = createDynamicTrackingState(\n isDebugDynamicAccesses\n )\n\n const { promise: runtimeStagePromise, resolve: resolveBlockedRuntimeAPIs } =\n createPromiseWithResolvers()\n\n const finalServerPrerenderStore: PrerenderStoreModernRuntime = {\n type: 'prerender-runtime',\n phase: 'render',\n rootParams,\n implicitTags,\n renderSignal: finalServerController.signal,\n controller: finalServerController,\n // All caches we could read must already be filled so no tracking is necessary\n cacheSignal: null,\n dynamicTracking: serverDynamicTracking,\n // Runtime prefetches are never cached server-side, only client-side,\n // so we set `expire` and `revalidate` to their minimum values just in case.\n revalidate: 1,\n expire: 0,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined,\n // Used to separate the \"Static\" stage from the \"Runtime\" stage.\n runtimeStagePromise,\n // These are not present in regular prerenders, but allowed in a runtime prerender.\n cookies,\n draftMode,\n }\n\n const finalRSCPayload = await workUnitAsyncStorage.run(\n finalServerPrerenderStore,\n getPayload\n )\n\n let prerenderIsPending = true\n const result = await prerenderAndAbortInSequentialTasksWithStages(\n async () => {\n // Static stage\n const prerenderResult = await workUnitAsyncStorage.run(\n finalServerPrerenderStore,\n ComponentMod.prerender,\n finalRSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError,\n signal: finalServerController.signal,\n }\n )\n prerenderIsPending = false\n return prerenderResult\n },\n () => {\n // Advance to the runtime stage.\n //\n // We make runtime APIs hang during the first task (above), and unblock them in the following task (here).\n // This makes sure that, at this point, we'll have finished all the static parts (what we'd prerender statically).\n // We know that they don't contain any incorrect sync IO, because that'd have caused a build error.\n // After we unblock Runtime APIs, if we encounter sync IO (e.g. `await cookies(); Date.now()`),\n // we'll abort, but we'll produce at least as much output as a static prerender would.\n resolveBlockedRuntimeAPIs()\n },\n () => {\n // Abort.\n if (finalServerController.signal.aborted) {\n // If the server controller is already aborted we must have called something\n // that required aborting the prerender synchronously such as with new Date()\n serverIsDynamic = true\n return\n }\n\n if (prerenderIsPending) {\n // If prerenderIsPending then we have blocked for longer than a Task and we assume\n // there is something unfinished.\n serverIsDynamic = true\n }\n finalServerController.abort()\n }\n )\n\n warnOnSyncDynamicError(serverDynamicTracking)\n\n return {\n result,\n // TODO(runtime-ppr): do we need to produce a digest map here?\n // digestErrorsMap: ...,\n dynamicAccess: serverDynamicTracking,\n isPartial: serverIsDynamic,\n collectedRevalidate: finalServerPrerenderStore.revalidate,\n collectedExpire: finalServerPrerenderStore.expire,\n collectedStale: selectStaleTime(finalServerPrerenderStore.stale),\n collectedTags: finalServerPrerenderStore.tags,\n }\n}\n\n/**\n * Performs a \"warmup\" render of the RSC payload for a given route. This function is called by the server\n * prior to an actual render request in Dev mode only. It's purpose is to fill caches so the actual render\n * can accurately log activity in the right render context (Prerender vs Render).\n *\n * At the moment this implementation is mostly a fork of generateDynamicFlightRenderResult\n */\nasync function warmupDevRender(\n req: BaseNextRequest,\n ctx: AppRenderContext\n): Promise {\n const {\n clientReferenceManifest,\n componentMod: ComponentMod,\n getDynamicParamFromSegment,\n implicitTags,\n renderOpts,\n workStore,\n } = ctx\n\n const {\n allowEmptyStaticShell = false,\n dev,\n onInstrumentationRequestError,\n } = renderOpts\n\n if (!dev) {\n throw new InvariantError(\n 'generateDynamicFlightRenderResult should never be called in `next start` mode.'\n )\n }\n\n const rootParams = getRootParams(\n ComponentMod.tree,\n getDynamicParamFromSegment\n )\n\n function onFlightDataRenderError(err: DigestedError) {\n return onInstrumentationRequestError?.(\n err,\n req,\n createErrorContext(ctx, 'react-server-components-payload')\n )\n }\n const onError = createFlightReactServerErrorHandler(\n true,\n onFlightDataRenderError\n )\n\n // We're doing a dev warmup, so we should create a new resume data cache so\n // we can fill it.\n const prerenderResumeDataCache = createPrerenderResumeDataCache()\n\n const renderController = new AbortController()\n const prerenderController = new AbortController()\n const reactController = new AbortController()\n const cacheSignal = new CacheSignal()\n\n const prerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n implicitTags,\n renderSignal: renderController.signal,\n controller: prerenderController,\n cacheSignal,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash: req.cookies[NEXT_HMR_REFRESH_HASH_COOKIE],\n captureOwnerStack: ComponentMod.captureOwnerStack,\n // warmup is a dev only feature and no fallback params are used in the\n // primary render which is static. We only use a prerender store here to\n // allow the warmup to halt on Request data APIs and fetches.\n fallbackRouteParams: null,\n }\n\n const rscPayload = await workUnitAsyncStorage.run(\n prerenderStore,\n generateDynamicRSCPayload,\n ctx\n )\n\n // For app dir, use the bundled version of Flight server renderer (renderToReadableStream)\n // which contains the subset React.\n workUnitAsyncStorage.run(\n prerenderStore,\n ComponentMod.renderToReadableStream,\n rscPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError,\n signal: renderController.signal,\n }\n )\n\n // Wait for all caches to be finished filling and for async imports to resolve\n trackPendingModules(cacheSignal)\n await cacheSignal.cacheReady()\n\n // We unset the cache so any late over-run renders aren't able to write into this cache\n prerenderStore.prerenderResumeDataCache = null\n // Abort the render\n reactController.abort()\n renderController.abort()\n\n // We don't really want to return a result here but the stack of functions\n // that calls into renderToHTML... expects a result. We should refactor this to\n // lift the warmup pathway outside of renderToHTML... but for now this suffices\n return new FlightRenderResult('', {\n fetchMetrics: workStore.fetchMetrics,\n renderResumeDataCache: createRenderResumeDataCache(\n prerenderResumeDataCache\n ),\n })\n}\n\n/**\n * Crawlers will inadvertently think the canonicalUrl in the RSC payload should be crawled\n * when our intention is to just seed the router state with the current URL.\n * This function splits up the pathname so that we can later join it on\n * when we're ready to consume the path.\n */\nfunction prepareInitialCanonicalUrl(url: RequestStore['url']) {\n return (url.pathname + url.search).split('/')\n}\n\n// This is the data necessary to render when no SSR errors are encountered\nasync function getRSCPayload(\n tree: LoaderTree,\n ctx: AppRenderContext,\n is404: boolean\n): Promise {\n const injectedCSS = new Set()\n const injectedJS = new Set()\n const injectedFontPreloadTags = new Set()\n let missingSlots: Set | undefined\n\n // We only track missing parallel slots in development\n if (process.env.NODE_ENV === 'development') {\n missingSlots = new Set()\n }\n\n const {\n getDynamicParamFromSegment,\n query,\n appUsingSizeAdjustment,\n componentMod: {\n createMetadataComponents,\n MetadataBoundary,\n ViewportBoundary,\n },\n url,\n workStore,\n } = ctx\n\n const initialTree = createFlightRouterStateFromLoaderTree(\n tree,\n getDynamicParamFromSegment,\n query\n )\n const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata\n const hasGlobalNotFound = !!tree[2]['global-not-found']\n\n const {\n ViewportTree,\n MetadataTree,\n getViewportReady,\n getMetadataReady,\n StreamingMetadataOutlet,\n } = createMetadataComponents({\n tree,\n // When it's using global-not-found, metadata errorType is undefined, which will retrieve the\n // metadata from the page.\n // When it's using not-found, metadata errorType is 'not-found', which will retrieve the\n // metadata from the not-found.js boundary.\n // TODO: remove this condition and keep it undefined when global-not-found is stabilized.\n errorType: is404 && !hasGlobalNotFound ? 'not-found' : undefined,\n parsedQuery: query,\n pathname: url.pathname,\n metadataContext: createMetadataContext(ctx.renderOpts),\n getDynamicParamFromSegment,\n appUsingSizeAdjustment,\n workStore,\n MetadataBoundary,\n ViewportBoundary,\n serveStreamingMetadata,\n })\n\n const preloadCallbacks: PreloadCallbacks = []\n\n const seedData = await createComponentTree({\n ctx,\n loaderTree: tree,\n parentParams: {},\n injectedCSS,\n injectedJS,\n injectedFontPreloadTags,\n rootLayoutIncluded: false,\n getViewportReady,\n getMetadataReady,\n missingSlots,\n preloadCallbacks,\n authInterrupts: ctx.renderOpts.experimental.authInterrupts,\n StreamingMetadataOutlet,\n })\n\n // When the `vary` response header is present with `Next-URL`, that means there's a chance\n // it could respond differently if there's an interception route. We provide this information\n // to `AppRouter` so that it can properly seed the prefetch cache with a prefix, if needed.\n const varyHeader = ctx.res.getHeader('vary')\n const couldBeIntercepted =\n typeof varyHeader === 'string' && varyHeader.includes(NEXT_URL)\n\n const initialHead = (\n \n \n \n \n \n )\n\n const { GlobalError, styles: globalErrorStyles } = await getGlobalErrorStyles(\n tree,\n ctx\n )\n\n // Assume the head we're rendering contains only partial data if PPR is\n // enabled and this is a statically generated response. This is used by the\n // client Segment Cache after a prefetch to determine if it can skip the\n // second request to fill in the dynamic data.\n //\n // See similar comment in create-component-tree.tsx for more context.\n const isPossiblyPartialHead =\n workStore.isStaticGeneration &&\n ctx.renderOpts.experimental.isRoutePPREnabled === true\n\n return {\n // See the comment above the `Preloads` component (below) for why this is part of the payload\n P: ,\n b: ctx.sharedContext.buildId,\n p: ctx.assetPrefix,\n c: prepareInitialCanonicalUrl(url),\n i: !!couldBeIntercepted,\n f: [\n [\n initialTree,\n seedData,\n initialHead,\n isPossiblyPartialHead,\n ] as FlightDataPath,\n ],\n m: missingSlots,\n G: [GlobalError, globalErrorStyles],\n s: typeof ctx.renderOpts.postponed === 'string',\n S: workStore.isStaticGeneration,\n }\n}\n\n/**\n * Preload calls (such as `ReactDOM.preloadStyle` and `ReactDOM.preloadFont`) need to be called during rendering\n * in order to create the appropriate preload tags in the DOM, otherwise they're a no-op. Since we invoke\n * renderToReadableStream with a function that returns component props rather than a component itself, we use\n * this component to \"render \" the preload calls.\n */\nfunction Preloads({ preloadCallbacks }: { preloadCallbacks: Function[] }) {\n preloadCallbacks.forEach((preloadFn) => preloadFn())\n return null\n}\n\n// This is the data necessary to render when an error state is triggered\nasync function getErrorRSCPayload(\n tree: LoaderTree,\n ctx: AppRenderContext,\n ssrError: unknown,\n errorType: MetadataErrorType | 'redirect' | undefined\n) {\n const {\n getDynamicParamFromSegment,\n query,\n appUsingSizeAdjustment,\n componentMod: {\n createMetadataComponents,\n MetadataBoundary,\n ViewportBoundary,\n },\n url,\n workStore,\n } = ctx\n\n const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata\n const { MetadataTree, ViewportTree } = createMetadataComponents({\n tree,\n parsedQuery: query,\n pathname: url.pathname,\n metadataContext: createMetadataContext(ctx.renderOpts),\n errorType,\n getDynamicParamFromSegment,\n appUsingSizeAdjustment,\n workStore,\n MetadataBoundary,\n ViewportBoundary,\n serveStreamingMetadata: serveStreamingMetadata,\n })\n\n const initialHead = (\n \n \n \n {process.env.NODE_ENV === 'development' && (\n \n )}\n \n \n )\n\n const initialTree = createFlightRouterStateFromLoaderTree(\n tree,\n getDynamicParamFromSegment,\n query\n )\n\n let err: Error | undefined = undefined\n if (ssrError) {\n err = isError(ssrError) ? ssrError : new Error(ssrError + '')\n }\n\n // For metadata notFound error there's no global not found boundary on top\n // so we create a not found page with AppRouter\n const seedData: CacheNodeSeedData = [\n initialTree[0],\n \n \n \n {process.env.NODE_ENV !== 'production' && err ? (\n \n ) : null}\n \n ,\n {},\n null,\n false,\n ]\n\n const { GlobalError, styles: globalErrorStyles } = await getGlobalErrorStyles(\n tree,\n ctx\n )\n\n const isPossiblyPartialHead =\n workStore.isStaticGeneration &&\n ctx.renderOpts.experimental.isRoutePPREnabled === true\n\n return {\n b: ctx.sharedContext.buildId,\n p: ctx.assetPrefix,\n c: prepareInitialCanonicalUrl(url),\n m: undefined,\n i: false,\n f: [\n [\n initialTree,\n seedData,\n initialHead,\n isPossiblyPartialHead,\n ] as FlightDataPath,\n ],\n G: [GlobalError, globalErrorStyles],\n s: typeof ctx.renderOpts.postponed === 'string',\n S: workStore.isStaticGeneration,\n } satisfies InitialRSCPayload\n}\n\nfunction assertClientReferenceManifest(\n clientReferenceManifest: RenderOpts['clientReferenceManifest']\n): asserts clientReferenceManifest is NonNullable<\n RenderOpts['clientReferenceManifest']\n> {\n if (!clientReferenceManifest) {\n throw new InvariantError('Expected clientReferenceManifest to be defined.')\n }\n}\n\n// This component must run in an SSR context. It will render the RSC root component\nfunction App({\n reactServerStream,\n preinitScripts,\n clientReferenceManifest,\n ServerInsertedHTMLProvider,\n nonce,\n}: {\n reactServerStream: BinaryStreamOf\n preinitScripts: () => void\n clientReferenceManifest: NonNullable\n ServerInsertedHTMLProvider: React.ComponentType<{ children: JSX.Element }>\n nonce?: string\n}): JSX.Element {\n preinitScripts()\n const response = React.use(\n useFlightStream(\n reactServerStream,\n clientReferenceManifest,\n nonce\n )\n )\n\n const initialState = createInitialRouterState({\n // This is not used during hydration, so we don't have to pass a\n // real timestamp.\n navigatedAt: -1,\n initialFlightData: response.f,\n initialCanonicalUrlParts: response.c,\n initialParallelRoutes: new Map(),\n // location is not initialized in the SSR render\n // it's set to window.location during hydration\n location: null,\n couldBeIntercepted: response.i,\n postponed: response.s,\n prerendered: response.S,\n })\n\n const actionQueue = createMutableActionQueue(initialState, null)\n\n const { HeadManagerContext } =\n require('../../shared/lib/head-manager-context.shared-runtime') as typeof import('../../shared/lib/head-manager-context.shared-runtime')\n\n return (\n \n \n \n \n \n )\n}\n\n// @TODO our error stream should be probably just use the same root component. But it was previously\n// different I don't want to figure out if that is meaningful at this time so just keeping the behavior\n// consistent for now.\nfunction ErrorApp({\n reactServerStream,\n preinitScripts,\n clientReferenceManifest,\n ServerInsertedHTMLProvider,\n nonce,\n}: {\n reactServerStream: BinaryStreamOf\n preinitScripts: () => void\n clientReferenceManifest: NonNullable\n ServerInsertedHTMLProvider: React.ComponentType<{ children: JSX.Element }>\n nonce?: string\n}): JSX.Element {\n preinitScripts()\n const response = React.use(\n useFlightStream(\n reactServerStream,\n clientReferenceManifest,\n nonce\n )\n )\n\n const initialState = createInitialRouterState({\n // This is not used during hydration, so we don't have to pass a\n // real timestamp.\n navigatedAt: -1,\n initialFlightData: response.f,\n initialCanonicalUrlParts: response.c,\n initialParallelRoutes: new Map(),\n // location is not initialized in the SSR render\n // it's set to window.location during hydration\n location: null,\n couldBeIntercepted: response.i,\n postponed: response.s,\n prerendered: response.S,\n })\n\n const actionQueue = createMutableActionQueue(initialState, null)\n\n return (\n \n \n \n )\n}\n\n// We use a trick with TS Generics to branch streams with a type so we can\n// consume the parsed value of a Readable Stream if it was constructed with a\n// certain object shape. The generic type is not used directly in the type so it\n// requires a disabling of the eslint rule disallowing unused vars\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type BinaryStreamOf = ReadableStream\n\nasync function renderToHTMLOrFlightImpl(\n req: BaseNextRequest,\n res: BaseNextResponse,\n url: ReturnType,\n pagePath: string,\n query: NextParsedUrlQuery,\n renderOpts: RenderOpts,\n workStore: WorkStore,\n parsedRequestHeaders: ParsedRequestHeaders,\n postponedState: PostponedState | null,\n serverComponentsHmrCache: ServerComponentsHmrCache | undefined,\n sharedContext: AppSharedContext,\n fallbackRouteParams: FallbackRouteParams | null\n) {\n const isNotFoundPath = pagePath === '/404'\n if (isNotFoundPath) {\n res.statusCode = 404\n }\n\n // A unique request timestamp used by development to ensure that it's\n // consistent and won't change during this request. This is important to\n // avoid that resources can be deduped by React Float if the same resource is\n // rendered or preloaded multiple times: ``.\n const requestTimestamp = Date.now()\n\n const {\n clientReferenceManifest,\n serverActionsManifest,\n ComponentMod,\n nextFontManifest,\n serverActions,\n assetPrefix = '',\n enableTainting,\n } = renderOpts\n\n // We need to expose the bundled `require` API globally for\n // react-server-dom-webpack. This is a hack until we find a better way.\n if (ComponentMod.__next_app__) {\n const instrumented = wrapClientComponentLoader(ComponentMod)\n\n // When we are prerendering if there is a cacheSignal for tracking\n // cache reads we track calls to `loadChunk` and `require`. This allows us\n // to treat chunk/module loading with similar semantics as cache reads to avoid\n // module loading from causing a prerender to abort too early.\n\n const shouldTrackModuleLoading = () => {\n if (!renderOpts.experimental.cacheComponents) {\n return false\n }\n if (renderOpts.dev) {\n return true\n }\n const workUnitStore = workUnitAsyncStorage.getStore()\n\n if (!workUnitStore) {\n return false\n }\n\n switch (workUnitStore.type) {\n case 'prerender':\n case 'prerender-client':\n case 'prerender-runtime':\n case 'cache':\n case 'private-cache':\n return true\n case 'prerender-ppr':\n case 'prerender-legacy':\n case 'request':\n case 'unstable-cache':\n return false\n default:\n workUnitStore satisfies never\n }\n }\n\n const __next_require__: typeof instrumented.require = (...args) => {\n const exportsOrPromise = instrumented.require(...args)\n if (shouldTrackModuleLoading()) {\n // requiring an async module returns a promise.\n trackPendingImport(exportsOrPromise)\n }\n return exportsOrPromise\n }\n // @ts-expect-error\n globalThis.__next_require__ = __next_require__\n\n const __next_chunk_load__: typeof instrumented.loadChunk = (...args) => {\n const loadingChunk = instrumented.loadChunk(...args)\n if (shouldTrackModuleLoading()) {\n trackPendingChunkLoad(loadingChunk)\n }\n return loadingChunk\n }\n // @ts-expect-error\n globalThis.__next_chunk_load__ = __next_chunk_load__\n }\n\n if (process.env.NODE_ENV === 'development') {\n // reset isr status at start of request\n const { pathname } = new URL(req.url || '/', 'http://n')\n renderOpts.setIsrStatus?.(pathname, null)\n }\n\n if (\n // The type check here ensures that `req` is correctly typed, and the\n // environment variable check provides dead code elimination.\n process.env.NEXT_RUNTIME !== 'edge' &&\n isNodeNextRequest(req)\n ) {\n res.onClose(() => {\n // We stop tracking fetch metrics when the response closes, since we\n // report them at that time.\n workStore.shouldTrackFetchMetrics = false\n })\n\n req.originalRequest.on('end', () => {\n if ('performance' in globalThis) {\n const metrics = getClientComponentLoaderMetrics({ reset: true })\n if (metrics) {\n getTracer()\n .startSpan(NextNodeServerSpan.clientComponentLoading, {\n startTime: metrics.clientComponentLoadStart,\n attributes: {\n 'next.clientComponentLoadCount':\n metrics.clientComponentLoadCount,\n 'next.span_type': NextNodeServerSpan.clientComponentLoading,\n },\n })\n .end(\n metrics.clientComponentLoadStart +\n metrics.clientComponentLoadTimes\n )\n }\n }\n })\n }\n\n const metadata: AppPageRenderResultMetadata = {\n statusCode: isNotFoundPath ? 404 : undefined,\n }\n\n const appUsingSizeAdjustment = !!nextFontManifest?.appUsingSizeAdjust\n\n assertClientReferenceManifest(clientReferenceManifest)\n\n const serverModuleMap = createServerModuleMap({ serverActionsManifest })\n\n setReferenceManifestsSingleton({\n page: workStore.page,\n clientReferenceManifest,\n serverActionsManifest,\n serverModuleMap,\n })\n\n ComponentMod.patchFetch()\n\n // Pull out the hooks/references from the component.\n const { tree: loaderTree, taintObjectReference } = ComponentMod\n if (enableTainting) {\n taintObjectReference(\n 'Do not pass process.env to Client Components since it will leak sensitive data',\n process.env\n )\n }\n\n workStore.fetchMetrics = []\n metadata.fetchMetrics = workStore.fetchMetrics\n\n // don't modify original query object\n query = { ...query }\n stripInternalQueries(query)\n\n const {\n flightRouterState,\n isPrefetchRequest,\n isRuntimePrefetchRequest,\n isRSCRequest,\n isDevWarmupRequest,\n isHmrRefresh,\n nonce,\n } = parsedRequestHeaders\n\n const { isStaticGeneration } = workStore\n\n /**\n * The metadata items array created in next-app-loader with all relevant information\n * that we need to resolve the final metadata.\n */\n let requestId: string\n\n if (isStaticGeneration) {\n requestId = Buffer.from(\n await crypto.subtle.digest('SHA-1', Buffer.from(req.url))\n ).toString('hex')\n } else if (process.env.NEXT_RUNTIME === 'edge') {\n requestId = crypto.randomUUID()\n } else {\n requestId = (\n require('next/dist/compiled/nanoid') as typeof import('next/dist/compiled/nanoid')\n ).nanoid()\n }\n\n /**\n * Dynamic parameters. E.g. when you visit `/dashboard/vercel` which is rendered by `/dashboard/[slug]` the value will be {\"slug\": \"vercel\"}.\n */\n const params = renderOpts.params ?? {}\n\n const getDynamicParamFromSegment = makeGetDynamicParamFromSegment(\n params,\n pagePath,\n fallbackRouteParams\n )\n\n const isPossibleActionRequest = getIsPossibleServerAction(req)\n\n const implicitTags = await getImplicitTags(\n workStore.page,\n url,\n fallbackRouteParams\n )\n\n const ctx: AppRenderContext = {\n componentMod: ComponentMod,\n url,\n renderOpts,\n workStore,\n parsedRequestHeaders,\n getDynamicParamFromSegment,\n query,\n isPrefetch: isPrefetchRequest,\n isPossibleServerAction: isPossibleActionRequest,\n requestTimestamp,\n appUsingSizeAdjustment,\n flightRouterState,\n requestId,\n pagePath,\n clientReferenceManifest,\n assetPrefix,\n isNotFoundPath,\n nonce,\n res,\n sharedContext,\n implicitTags,\n }\n\n getTracer().setRootSpanAttribute('next.route', pagePath)\n\n if (isStaticGeneration) {\n // We're either building or revalidating. In either case we need to\n // prerender our page rather than render it.\n const prerenderToStreamWithTracing = getTracer().wrap(\n AppRenderSpan.getBodyResult,\n {\n spanName: `prerender route (app) ${pagePath}`,\n attributes: {\n 'next.route': pagePath,\n },\n },\n prerenderToStream\n )\n\n const response = await prerenderToStreamWithTracing(\n req,\n res,\n ctx,\n metadata,\n loaderTree,\n fallbackRouteParams\n )\n\n // If we're debugging partial prerendering, print all the dynamic API accesses\n // that occurred during the render.\n // @TODO move into renderToStream function\n if (\n response.dynamicAccess &&\n accessedDynamicData(response.dynamicAccess) &&\n renderOpts.isDebugDynamicAccesses\n ) {\n warn('The following dynamic usage was detected:')\n for (const access of formatDynamicAPIAccesses(response.dynamicAccess)) {\n warn(access)\n }\n }\n\n // If we encountered any unexpected errors during build we fail the\n // prerendering phase and the build.\n if (workStore.invalidDynamicUsageError) {\n logDisallowedDynamicError(workStore, workStore.invalidDynamicUsageError)\n throw new StaticGenBailoutError()\n }\n if (response.digestErrorsMap.size) {\n const buildFailingError = response.digestErrorsMap.values().next().value\n if (buildFailingError) throw buildFailingError\n }\n // Pick first userland SSR error, which is also not a RSC error.\n if (response.ssrErrors.length) {\n const buildFailingError = response.ssrErrors.find((err) =>\n isUserLandError(err)\n )\n if (buildFailingError) throw buildFailingError\n }\n\n const options: RenderResultOptions = {\n metadata,\n contentType: HTML_CONTENT_TYPE_HEADER,\n }\n // If we have pending revalidates, wait until they are all resolved.\n if (\n workStore.pendingRevalidates ||\n workStore.pendingRevalidateWrites ||\n workStore.pendingRevalidatedTags\n ) {\n const pendingPromise = executeRevalidates(workStore).finally(() => {\n if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {\n console.log('pending revalidates promise finished for:', url)\n }\n })\n\n if (renderOpts.waitUntil) {\n renderOpts.waitUntil(pendingPromise)\n } else {\n options.waitUntil = pendingPromise\n }\n }\n\n applyMetadataFromPrerenderResult(response, metadata, workStore)\n\n if (response.renderResumeDataCache) {\n metadata.renderResumeDataCache = response.renderResumeDataCache\n }\n\n return new RenderResult(await streamToString(response.stream), options)\n } else {\n // We're rendering dynamically\n const renderResumeDataCache =\n renderOpts.renderResumeDataCache ?? postponedState?.renderResumeDataCache\n\n const rootParams = getRootParams(loaderTree, ctx.getDynamicParamFromSegment)\n const devValidatingFallbackParams =\n getRequestMeta(req, 'devValidatingFallbackParams') || null\n const requestStore = createRequestStoreForRender(\n req,\n res,\n url,\n rootParams,\n implicitTags,\n renderOpts.onUpdateCookies,\n renderOpts.previewProps,\n isHmrRefresh,\n serverComponentsHmrCache,\n renderResumeDataCache,\n devValidatingFallbackParams\n )\n\n if (\n process.env.NODE_ENV === 'development' &&\n renderOpts.setIsrStatus &&\n // The type check here ensures that `req` is correctly typed, and the\n // environment variable check provides dead code elimination.\n process.env.NEXT_RUNTIME !== 'edge' &&\n isNodeNextRequest(req) &&\n !isDevWarmupRequest\n ) {\n const setIsrStatus = renderOpts.setIsrStatus\n req.originalRequest.on('end', () => {\n if (!requestStore.usedDynamic && !workStore.forceDynamic) {\n // only node can be ISR so we only need to update the status here\n const { pathname } = new URL(req.url || '/', 'http://n')\n setIsrStatus(pathname, true)\n }\n })\n }\n\n if (isDevWarmupRequest) {\n return warmupDevRender(req, ctx)\n } else if (isRSCRequest) {\n if (isRuntimePrefetchRequest) {\n return generateRuntimePrefetchResult(req, res, ctx, requestStore)\n } else {\n return generateDynamicFlightRenderResult(req, ctx, requestStore)\n }\n }\n\n const renderToStreamWithTracing = getTracer().wrap(\n AppRenderSpan.getBodyResult,\n {\n spanName: `render route (app) ${pagePath}`,\n attributes: {\n 'next.route': pagePath,\n },\n },\n renderToStream\n )\n\n let formState: null | any = null\n if (isPossibleActionRequest) {\n // For action requests, we handle them differently with a special render result.\n const actionRequestResult = await handleAction({\n req,\n res,\n ComponentMod,\n serverModuleMap,\n generateFlight: generateDynamicFlightRenderResult,\n workStore,\n requestStore,\n serverActions,\n ctx,\n metadata,\n })\n\n if (actionRequestResult) {\n if (actionRequestResult.type === 'not-found') {\n const notFoundLoaderTree = createNotFoundLoaderTree(loaderTree)\n res.statusCode = 404\n metadata.statusCode = 404\n const stream = await renderToStreamWithTracing(\n requestStore,\n req,\n res,\n ctx,\n notFoundLoaderTree,\n formState,\n postponedState,\n metadata,\n devValidatingFallbackParams\n )\n\n return new RenderResult(stream, {\n metadata,\n contentType: HTML_CONTENT_TYPE_HEADER,\n })\n } else if (actionRequestResult.type === 'done') {\n if (actionRequestResult.result) {\n actionRequestResult.result.assignMetadata(metadata)\n return actionRequestResult.result\n } else if (actionRequestResult.formState) {\n formState = actionRequestResult.formState\n }\n }\n }\n }\n\n const options: RenderResultOptions = {\n metadata,\n contentType: HTML_CONTENT_TYPE_HEADER,\n }\n\n const stream = await renderToStreamWithTracing(\n requestStore,\n req,\n res,\n ctx,\n loaderTree,\n formState,\n postponedState,\n metadata,\n devValidatingFallbackParams\n )\n\n // Invalid dynamic usages should only error the request in development.\n // In production, it's better to produce a result.\n // (the dynamic error will still be thrown inside the component tree, but it's catchable by error boundaries)\n if (workStore.invalidDynamicUsageError && workStore.dev) {\n throw workStore.invalidDynamicUsageError\n }\n\n // If we have pending revalidates, wait until they are all resolved.\n if (\n workStore.pendingRevalidates ||\n workStore.pendingRevalidateWrites ||\n workStore.pendingRevalidatedTags\n ) {\n const pendingPromise = executeRevalidates(workStore).finally(() => {\n if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {\n console.log('pending revalidates promise finished for:', url)\n }\n })\n\n if (renderOpts.waitUntil) {\n renderOpts.waitUntil(pendingPromise)\n } else {\n options.waitUntil = pendingPromise\n }\n }\n\n // Create the new render result for the response.\n return new RenderResult(stream, options)\n }\n}\n\nexport type AppPageRender = (\n req: BaseNextRequest,\n res: BaseNextResponse,\n pagePath: string,\n query: NextParsedUrlQuery,\n fallbackRouteParams: FallbackRouteParams | null,\n renderOpts: RenderOpts,\n serverComponentsHmrCache: ServerComponentsHmrCache | undefined,\n isDevWarmup: boolean,\n sharedContext: AppSharedContext\n) => Promise>\n\nexport const renderToHTMLOrFlight: AppPageRender = (\n req,\n res,\n pagePath,\n query,\n fallbackRouteParams,\n renderOpts,\n serverComponentsHmrCache,\n isDevWarmup,\n sharedContext\n) => {\n if (!req.url) {\n throw new Error('Invalid URL')\n }\n\n const url = parseRelativeUrl(req.url, undefined, false)\n\n // We read these values from the request object as, in certain cases,\n // base-server will strip them to opt into different rendering behavior.\n const parsedRequestHeaders = parseRequestHeaders(req.headers, {\n isDevWarmup,\n isRoutePPREnabled: renderOpts.experimental.isRoutePPREnabled === true,\n previewModeId: renderOpts.previewProps?.previewModeId,\n })\n\n const { isPrefetchRequest, previouslyRevalidatedTags } = parsedRequestHeaders\n\n let postponedState: PostponedState | null = null\n\n // If provided, the postpone state should be parsed so it can be provided to\n // React.\n if (typeof renderOpts.postponed === 'string') {\n if (fallbackRouteParams) {\n throw new InvariantError(\n 'postponed state should not be provided when fallback params are provided'\n )\n }\n\n postponedState = parsePostponedState(\n renderOpts.postponed,\n renderOpts.params\n )\n }\n\n if (\n postponedState?.renderResumeDataCache &&\n renderOpts.renderResumeDataCache\n ) {\n throw new InvariantError(\n 'postponed state and dev warmup immutable resume data cache should not be provided together'\n )\n }\n\n const workStore = createWorkStore({\n page: renderOpts.routeModule.definition.page,\n renderOpts,\n // @TODO move to workUnitStore of type Request\n isPrefetchRequest,\n buildId: sharedContext.buildId,\n previouslyRevalidatedTags,\n })\n\n return workAsyncStorage.run(\n workStore,\n // The function to run\n renderToHTMLOrFlightImpl,\n // all of it's args\n req,\n res,\n url,\n pagePath,\n query,\n renderOpts,\n workStore,\n parsedRequestHeaders,\n postponedState,\n serverComponentsHmrCache,\n sharedContext,\n fallbackRouteParams\n )\n}\n\nfunction applyMetadataFromPrerenderResult(\n response: Pick<\n PrerenderToStreamResult,\n | 'collectedExpire'\n | 'collectedRevalidate'\n | 'collectedStale'\n | 'collectedTags'\n >,\n metadata: AppPageRenderResultMetadata,\n workStore: WorkStore\n) {\n if (response.collectedTags) {\n metadata.fetchTags = response.collectedTags.join(',')\n }\n\n // Let the client router know how long to keep the cached entry around.\n const staleHeader = String(response.collectedStale)\n metadata.headers ??= {}\n metadata.headers[NEXT_ROUTER_STALE_TIME_HEADER] = staleHeader\n\n // If force static is specifically set to false, we should not revalidate\n // the page.\n if (workStore.forceStatic === false || response.collectedRevalidate === 0) {\n metadata.cacheControl = { revalidate: 0, expire: undefined }\n } else {\n // Copy the cache control value onto the render result metadata.\n metadata.cacheControl = {\n revalidate:\n response.collectedRevalidate >= INFINITE_CACHE\n ? false\n : response.collectedRevalidate,\n expire:\n response.collectedExpire >= INFINITE_CACHE\n ? undefined\n : response.collectedExpire,\n }\n }\n\n // provide bailout info for debugging\n if (metadata.cacheControl?.revalidate === 0) {\n metadata.staticBailoutInfo = {\n description: workStore.dynamicUsageDescription,\n stack: workStore.dynamicUsageStack,\n }\n }\n}\n\nasync function renderToStream(\n requestStore: RequestStore,\n req: BaseNextRequest,\n res: BaseNextResponse,\n ctx: AppRenderContext,\n tree: LoaderTree,\n formState: any,\n postponedState: PostponedState | null,\n metadata: AppPageRenderResultMetadata,\n devValidatingFallbackParams: FallbackRouteParams | null\n): Promise> {\n const { assetPrefix, nonce, pagePath, renderOpts } = ctx\n\n const {\n basePath,\n buildManifest,\n clientReferenceManifest,\n ComponentMod,\n crossOrigin,\n dev = false,\n experimental,\n nextExport = false,\n onInstrumentationRequestError,\n page,\n reactMaxHeadersLength,\n shouldWaitOnAllReady,\n subresourceIntegrityManifest,\n supportsDynamicResponse,\n } = renderOpts\n\n assertClientReferenceManifest(clientReferenceManifest)\n\n const { ServerInsertedHTMLProvider, renderServerInsertedHTML } =\n createServerInsertedHTML()\n const getServerInsertedMetadata = createServerInsertedMetadata(nonce)\n\n const tracingMetadata = getTracedMetadata(\n getTracer().getTracePropagationData(),\n experimental.clientTraceMetadata\n )\n\n const polyfills: JSX.IntrinsicElements['script'][] =\n buildManifest.polyfillFiles\n .filter(\n (polyfill) =>\n polyfill.endsWith('.js') && !polyfill.endsWith('.module.js')\n )\n .map((polyfill) => ({\n src: `${assetPrefix}/_next/${polyfill}${getAssetQueryString(\n ctx,\n false\n )}`,\n integrity: subresourceIntegrityManifest?.[polyfill],\n crossOrigin,\n noModule: true,\n nonce,\n }))\n\n const [preinitScripts, bootstrapScript] = getRequiredScripts(\n buildManifest,\n // Why is assetPrefix optional on renderOpts?\n // @TODO make it default empty string on renderOpts and get rid of it from ctx\n assetPrefix,\n crossOrigin,\n subresourceIntegrityManifest,\n getAssetQueryString(ctx, true),\n nonce,\n page\n )\n\n const reactServerErrorsByDigest: Map = new Map()\n const silenceLogger = false\n function onHTMLRenderRSCError(err: DigestedError) {\n return onInstrumentationRequestError?.(\n err,\n req,\n createErrorContext(ctx, 'react-server-components')\n )\n }\n const serverComponentsErrorHandler = createHTMLReactServerErrorHandler(\n dev,\n nextExport,\n reactServerErrorsByDigest,\n silenceLogger,\n onHTMLRenderRSCError\n )\n\n function onHTMLRenderSSRError(err: DigestedError) {\n return onInstrumentationRequestError?.(\n err,\n req,\n createErrorContext(ctx, 'server-rendering')\n )\n }\n\n const allCapturedErrors: Array = []\n const htmlRendererErrorHandler = createHTMLErrorHandler(\n dev,\n nextExport,\n reactServerErrorsByDigest,\n allCapturedErrors,\n silenceLogger,\n onHTMLRenderSSRError\n )\n\n let reactServerResult: null | ReactServerResult = null\n\n const setHeader = res.setHeader.bind(res)\n const appendHeader = res.appendHeader.bind(res)\n\n try {\n if (\n // We only want this behavior when running `next dev`\n dev &&\n // We only want this behavior when we have React's dev builds available\n process.env.NODE_ENV === 'development' &&\n // Edge routes never prerender so we don't have a Prerender environment for anything in edge runtime\n process.env.NEXT_RUNTIME !== 'edge' &&\n // We only have a Prerender environment for projects opted into cacheComponents\n experimental.cacheComponents\n ) {\n // This is a dynamic render. We don't do dynamic tracking because we're not prerendering\n const RSCPayload: InitialRSCPayload & {\n /** Only available during cacheComponents development builds. Used for logging errors. */\n _validation?: Promise\n } = await workUnitAsyncStorage.run(\n requestStore,\n getRSCPayload,\n tree,\n ctx,\n res.statusCode === 404\n )\n const [resolveValidation, validationOutlet] = createValidationOutlet()\n RSCPayload._validation = validationOutlet\n\n const reactServerStream = await workUnitAsyncStorage.run(\n requestStore,\n scheduleInSequentialTasks,\n () => {\n requestStore.prerenderPhase = true\n return ComponentMod.renderToReadableStream(\n RSCPayload,\n clientReferenceManifest.clientModules,\n {\n onError: serverComponentsErrorHandler,\n environmentName: () =>\n requestStore.prerenderPhase === true ? 'Prerender' : 'Server',\n filterStackFrame,\n }\n )\n },\n () => {\n requestStore.prerenderPhase = false\n }\n )\n\n spawnDynamicValidationInDev(\n resolveValidation,\n tree,\n ctx,\n res.statusCode === 404,\n clientReferenceManifest,\n requestStore,\n devValidatingFallbackParams\n )\n\n reactServerResult = new ReactServerResult(reactServerStream)\n } else {\n // This is a dynamic render. We don't do dynamic tracking because we're not prerendering\n const RSCPayload = await workUnitAsyncStorage.run(\n requestStore,\n getRSCPayload,\n tree,\n ctx,\n res.statusCode === 404\n )\n\n reactServerResult = new ReactServerResult(\n workUnitAsyncStorage.run(\n requestStore,\n ComponentMod.renderToReadableStream,\n RSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: serverComponentsErrorHandler,\n }\n )\n )\n }\n\n // React doesn't start rendering synchronously but we want the RSC render to have a chance to start\n // before we begin SSR rendering because we want to capture any available preload headers so we tick\n // one task before continuing\n await waitAtLeastOneReactRenderTask()\n\n // If provided, the postpone state should be parsed as JSON so it can be\n // provided to React.\n if (typeof renderOpts.postponed === 'string') {\n if (postponedState?.type === DynamicState.DATA) {\n // We have a complete HTML Document in the prerender but we need to\n // still include the new server component render because it was not included\n // in the static prelude.\n const inlinedReactServerDataStream = createInlinedDataReadableStream(\n reactServerResult.tee(),\n nonce,\n formState\n )\n\n return chainStreams(\n inlinedReactServerDataStream,\n createDocumentClosingStream()\n )\n } else if (postponedState) {\n // We assume we have dynamic HTML requiring a resume render to complete\n const { postponed, preludeState } =\n getPostponedFromState(postponedState)\n const resume = (\n require('react-dom/server') as typeof import('react-dom/server')\n ).resume\n\n const htmlStream = await workUnitAsyncStorage.run(\n requestStore,\n resume,\n ,\n postponed,\n { onError: htmlRendererErrorHandler, nonce }\n )\n\n const getServerInsertedHTML = makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: allCapturedErrors,\n basePath,\n tracingMetadata: tracingMetadata,\n })\n return await continueDynamicHTMLResume(htmlStream, {\n // If the prelude is empty (i.e. is no static shell), we should wait for initial HTML to be rendered\n // to avoid injecting RSC data too early.\n // If we have a non-empty-prelude (i.e. a static HTML shell), then it's already been sent separately,\n // so we shouldn't wait for any HTML to be emitted from the resume before sending RSC data.\n delayDataUntilFirstHtmlChunk:\n preludeState === DynamicHTMLPreludeState.Empty,\n inlinedDataStream: createInlinedDataReadableStream(\n reactServerResult.consume(),\n nonce,\n formState\n ),\n getServerInsertedHTML,\n getServerInsertedMetadata,\n })\n }\n }\n\n // This is a regular dynamic render\n const renderToReadableStream = (\n require('react-dom/server') as typeof import('react-dom/server')\n ).renderToReadableStream\n\n const htmlStream = await workUnitAsyncStorage.run(\n requestStore,\n renderToReadableStream,\n ,\n {\n onError: htmlRendererErrorHandler,\n nonce,\n onHeaders: (headers: Headers) => {\n headers.forEach((value, key) => {\n appendHeader(key, value)\n })\n },\n maxHeadersLength: reactMaxHeadersLength,\n bootstrapScripts: [bootstrapScript],\n formState,\n }\n )\n\n const getServerInsertedHTML = makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: allCapturedErrors,\n basePath,\n tracingMetadata: tracingMetadata,\n })\n /**\n * Rules of Static & Dynamic HTML:\n *\n * 1.) We must generate static HTML unless the caller explicitly opts\n * in to dynamic HTML support.\n *\n * 2.) If dynamic HTML support is requested, we must honor that request\n * or throw an error. It is the sole responsibility of the caller to\n * ensure they aren't e.g. requesting dynamic HTML for an AMP page.\n *\n * 3.) If `shouldWaitOnAllReady` is true, which indicates we need to\n * resolve all suspenses and generate a full HTML. e.g. when it's a\n * html limited bot requests, we produce the full HTML content.\n *\n * These rules help ensure that other existing features like request caching,\n * coalescing, and ISR continue working as intended.\n */\n const generateStaticHTML =\n supportsDynamicResponse !== true || !!shouldWaitOnAllReady\n\n return await continueFizzStream(htmlStream, {\n inlinedDataStream: createInlinedDataReadableStream(\n reactServerResult.consume(),\n nonce,\n formState\n ),\n isStaticGeneration: generateStaticHTML,\n isBuildTimePrerendering: ctx.workStore.isBuildTimePrerendering === true,\n buildId: ctx.workStore.buildId,\n getServerInsertedHTML,\n getServerInsertedMetadata,\n validateRootLayout: dev,\n })\n } catch (err) {\n if (\n isStaticGenBailoutError(err) ||\n (typeof err === 'object' &&\n err !== null &&\n 'message' in err &&\n typeof err.message === 'string' &&\n err.message.includes(\n 'https://nextjs.org/docs/advanced-features/static-html-export'\n ))\n ) {\n // Ensure that \"next dev\" prints the red error overlay\n throw err\n }\n\n // If a bailout made it to this point, it means it wasn't wrapped inside\n // a suspense boundary.\n const shouldBailoutToCSR = isBailoutToCSRError(err)\n if (shouldBailoutToCSR) {\n const stack = getStackWithoutErrorMessage(err)\n error(\n `${err.reason} should be wrapped in a suspense boundary at page \"${pagePath}\". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout\\n${stack}`\n )\n\n throw err\n }\n\n let errorType: MetadataErrorType | 'redirect' | undefined\n\n if (isHTTPAccessFallbackError(err)) {\n res.statusCode = getAccessFallbackHTTPStatus(err)\n metadata.statusCode = res.statusCode\n errorType = getAccessFallbackErrorTypeByStatus(res.statusCode)\n } else if (isRedirectError(err)) {\n errorType = 'redirect'\n res.statusCode = getRedirectStatusCodeFromError(err)\n metadata.statusCode = res.statusCode\n\n const redirectUrl = addPathPrefix(getURLFromRedirectError(err), basePath)\n\n // If there were mutable cookies set, we need to set them on the\n // response.\n const headers = new Headers()\n if (appendMutableCookies(headers, requestStore.mutableCookies)) {\n setHeader('set-cookie', Array.from(headers.values()))\n }\n\n setHeader('location', redirectUrl)\n } else if (!shouldBailoutToCSR) {\n res.statusCode = 500\n metadata.statusCode = res.statusCode\n }\n\n const [errorPreinitScripts, errorBootstrapScript] = getRequiredScripts(\n buildManifest,\n assetPrefix,\n crossOrigin,\n subresourceIntegrityManifest,\n getAssetQueryString(ctx, false),\n nonce,\n '/_not-found/page'\n )\n\n const errorRSCPayload = await workUnitAsyncStorage.run(\n requestStore,\n getErrorRSCPayload,\n tree,\n ctx,\n reactServerErrorsByDigest.has((err as any).digest) ? null : err,\n errorType\n )\n\n const errorServerStream = workUnitAsyncStorage.run(\n requestStore,\n ComponentMod.renderToReadableStream,\n errorRSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: serverComponentsErrorHandler,\n }\n )\n\n if (reactServerResult === null) {\n // We errored when we did not have an RSC stream to read from. This is not just a render\n // error, we need to throw early\n throw err\n }\n\n try {\n const fizzStream = await workUnitAsyncStorage.run(\n requestStore,\n renderToInitialFizzStream,\n {\n ReactDOMServer:\n require('react-dom/server') as typeof import('react-dom/server'),\n element: (\n \n ),\n streamOptions: {\n nonce,\n // Include hydration scripts in the HTML\n bootstrapScripts: [errorBootstrapScript],\n formState,\n },\n }\n )\n\n /**\n * Rules of Static & Dynamic HTML:\n *\n * 1.) We must generate static HTML unless the caller explicitly opts\n * in to dynamic HTML support.\n *\n * 2.) If dynamic HTML support is requested, we must honor that request\n * or throw an error. It is the sole responsibility of the caller to\n * ensure they aren't e.g. requesting dynamic HTML for an AMP page.\n * 3.) If `shouldWaitOnAllReady` is true, which indicates we need to\n * resolve all suspenses and generate a full HTML. e.g. when it's a\n * html limited bot requests, we produce the full HTML content.\n *\n * These rules help ensure that other existing features like request caching,\n * coalescing, and ISR continue working as intended.\n */\n const generateStaticHTML =\n supportsDynamicResponse !== true || !!shouldWaitOnAllReady\n return await continueFizzStream(fizzStream, {\n inlinedDataStream: createInlinedDataReadableStream(\n // This is intentionally using the readable datastream from the\n // main render rather than the flight data from the error page\n // render\n reactServerResult.consume(),\n nonce,\n formState\n ),\n isStaticGeneration: generateStaticHTML,\n isBuildTimePrerendering: ctx.workStore.isBuildTimePrerendering === true,\n buildId: ctx.workStore.buildId,\n getServerInsertedHTML: makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: [],\n basePath,\n tracingMetadata: tracingMetadata,\n }),\n getServerInsertedMetadata,\n validateRootLayout: dev,\n })\n } catch (finalErr: any) {\n if (\n process.env.NODE_ENV === 'development' &&\n isHTTPAccessFallbackError(finalErr)\n ) {\n const { bailOnRootNotFound } =\n require('../../client/components/dev-root-http-access-fallback-boundary') as typeof import('../../client/components/dev-root-http-access-fallback-boundary')\n bailOnRootNotFound()\n }\n throw finalErr\n }\n }\n}\n\nfunction createValidationOutlet() {\n let resolveValidation: (value: React.ReactNode) => void\n let outlet = new Promise((resolve) => {\n resolveValidation = resolve\n })\n return [resolveValidation!, outlet] as const\n}\n\n/**\n * This function is a fork of prerenderToStream cacheComponents branch.\n * While it doesn't return a stream we want it to have identical\n * prerender semantics to prerenderToStream and should update it\n * in conjunction with any changes to that function.\n */\nasync function spawnDynamicValidationInDev(\n resolveValidation: (validatingElement: React.ReactNode) => void,\n tree: LoaderTree,\n ctx: AppRenderContext,\n isNotFound: boolean,\n clientReferenceManifest: NonNullable,\n requestStore: RequestStore,\n fallbackRouteParams: FallbackRouteParams | null\n): Promise {\n const {\n componentMod: ComponentMod,\n getDynamicParamFromSegment,\n implicitTags,\n nonce,\n renderOpts,\n workStore,\n } = ctx\n\n const { allowEmptyStaticShell = false } = renderOpts\n\n // These values are placeholder values for this validating render\n // that are provided during the actual prerenderToStream.\n const preinitScripts = () => {}\n const { ServerInsertedHTMLProvider } = createServerInsertedHTML()\n\n const rootParams = getRootParams(\n ComponentMod.tree,\n getDynamicParamFromSegment\n )\n\n const hmrRefreshHash = requestStore.cookies.get(\n NEXT_HMR_REFRESH_HASH_COOKIE\n )?.value\n\n // The prerender controller represents the lifetime of the prerender. It will\n // be aborted when a task is complete or a synchronously aborting API is\n // called. Notably, during prospective prerenders, this does not actually\n // terminate the prerender itself, which will continue until all caches are\n // filled.\n const initialServerPrerenderController = new AbortController()\n\n // This controller is used to abort the React prerender.\n const initialServerReactController = new AbortController()\n\n // This controller represents the lifetime of the React prerender. Its signal\n // can be used for any I/O operation to abort the I/O and/or to reject, when\n // prerendering aborts. This includes our own hanging promises for accessing\n // request data, and for fetch calls. It might be replaced in the future by\n // React.cacheSignal(). It's aborted after the React controller, so that no\n // pending I/O can register abort listeners that are called before React's\n // abort listener is called. This ensures that pending I/O is not rejected too\n // early when aborting the prerender. Notably, during the prospective\n // prerender, it is different from the prerender controller because we don't\n // want to end the React prerender until all caches are filled.\n const initialServerRenderController = new AbortController()\n\n // The cacheSignal helps us track whether caches are still filling or we are\n // ready to cut the render off.\n const cacheSignal = new CacheSignal()\n\n const captureOwnerStackClient = React.captureOwnerStack\n const captureOwnerStackServer = ComponentMod.captureOwnerStack\n\n // The resume data cache here should use a fresh instance as it's\n // performing a fresh prerender. If we get to implementing the\n // prerendering of an already prerendered page, we should use the passed\n // resume data cache instead.\n const prerenderResumeDataCache = createPrerenderResumeDataCache()\n const initialServerPayloadPrerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n // While this render signal isn't going to be used to abort a React render while getting the RSC payload\n // various request data APIs bind to this controller to reject after completion.\n renderSignal: initialServerRenderController.signal,\n // When we generate the RSC payload we might abort this controller due to sync IO\n // but we don't actually care about sync IO in this phase so we use a throw away controller\n // that isn't connected to anything\n controller: new AbortController(),\n // During the initial prerender we need to track all cache reads to ensure\n // we render long enough to fill every cache it is possible to visit during\n // the final prerender.\n cacheSignal,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash,\n captureOwnerStack: captureOwnerStackServer,\n }\n\n // We're not going to use the result of this render because the only time it could be used\n // is if it completes in a microtask and that's likely very rare for any non-trivial app\n const initialServerPayload = await workUnitAsyncStorage.run(\n initialServerPayloadPrerenderStore,\n getRSCPayload,\n tree,\n ctx,\n isNotFound\n )\n\n const initialServerPrerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: initialServerRenderController.signal,\n controller: initialServerPrerenderController,\n // During the initial prerender we need to track all cache reads to ensure\n // we render long enough to fill every cache it is possible to visit during\n // the final prerender.\n cacheSignal,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash,\n captureOwnerStack: captureOwnerStackServer,\n }\n\n const pendingInitialServerResult = workUnitAsyncStorage.run(\n initialServerPrerenderStore,\n ComponentMod.prerender,\n initialServerPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: (err) => {\n const digest = getDigestForWellKnownError(err)\n\n if (digest) {\n return digest\n }\n\n if (isReactLargeShellError(err)) {\n // TODO: Aggregate\n console.error(err)\n return undefined\n }\n\n if (initialServerPrerenderController.signal.aborted) {\n // The render aborted before this error was handled which indicates\n // the error is caused by unfinished components within the render\n return\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n },\n // we don't care to track postpones during the prospective render because we need\n // to always do a final render anyway\n onPostpone: undefined,\n // We don't want to stop rendering until the cacheSignal is complete so we pass\n // a different signal to this render call than is used by dynamic APIs to signify\n // transitioning out of the prerender environment\n signal: initialServerReactController.signal,\n }\n )\n\n // The listener to abort our own render controller must be added after React\n // has added its listener, to ensure that pending I/O is not aborted/rejected\n // too early.\n initialServerReactController.signal.addEventListener(\n 'abort',\n () => {\n initialServerRenderController.abort()\n },\n { once: true }\n )\n\n // Wait for all caches to be finished filling and for async imports to resolve\n trackPendingModules(cacheSignal)\n await cacheSignal.cacheReady()\n\n initialServerReactController.abort()\n\n // We don't need to continue the prerender process if we already\n // detected invalid dynamic usage in the initial prerender phase.\n const { invalidDynamicUsageError } = workStore\n if (invalidDynamicUsageError) {\n resolveValidation(\n {\n console.error(invalidDynamicUsageError)\n }}\n />\n )\n return\n }\n\n let initialServerResult\n try {\n initialServerResult = await createReactServerPrerenderResult(\n pendingInitialServerResult\n )\n } catch (err) {\n if (\n initialServerReactController.signal.aborted ||\n initialServerPrerenderController.signal.aborted\n ) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n }\n\n if (initialServerResult) {\n const initialClientPrerenderController = new AbortController()\n const initialClientReactController = new AbortController()\n const initialClientRenderController = new AbortController()\n\n const initialClientPrerenderStore: PrerenderStore = {\n type: 'prerender-client',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: initialClientRenderController.signal,\n controller: initialClientPrerenderController,\n // For HTML Generation the only cache tracked activity\n // is module loading, which has it's own cache signal\n cacheSignal: null,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash: undefined,\n captureOwnerStack: captureOwnerStackClient,\n }\n\n const prerender = (\n require('react-dom/static') as typeof import('react-dom/static')\n ).prerender\n const pendingInitialClientResult = workUnitAsyncStorage.run(\n initialClientPrerenderStore,\n prerender,\n ,\n {\n signal: initialClientReactController.signal,\n onError: (err) => {\n const digest = getDigestForWellKnownError(err)\n\n if (digest) {\n return digest\n }\n\n if (isReactLargeShellError(err)) {\n // TODO: Aggregate\n console.error(err)\n return undefined\n }\n\n if (initialClientReactController.signal.aborted) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n },\n // We don't need bootstrap scripts in this prerender\n // bootstrapScripts: [bootstrapScript],\n }\n )\n\n // The listener to abort our own render controller must be added after React\n // has added its listener, to ensure that pending I/O is not\n // aborted/rejected too early.\n initialClientReactController.signal.addEventListener(\n 'abort',\n () => {\n initialClientRenderController.abort()\n },\n { once: true }\n )\n\n pendingInitialClientResult.catch((err) => {\n if (\n initialClientReactController.signal.aborted ||\n isPrerenderInterruptedError(err)\n ) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n })\n\n // This is mostly needed for dynamic `import()`s in client components.\n // Promises passed to client were already awaited above (assuming that they came from cached functions)\n trackPendingModules(cacheSignal)\n await cacheSignal.cacheReady()\n initialClientReactController.abort()\n }\n\n const finalServerReactController = new AbortController()\n const finalServerRenderController = new AbortController()\n\n const finalServerPayloadPrerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n // While this render signal isn't going to be used to abort a React render while getting the RSC payload\n // various request data APIs bind to this controller to reject after completion.\n renderSignal: finalServerRenderController.signal,\n // When we generate the RSC payload we might abort this controller due to sync IO\n // but we don't actually care about sync IO in this phase so we use a throw away controller\n // that isn't connected to anything\n controller: new AbortController(),\n // All caches we could read must already be filled so no tracking is necessary\n cacheSignal: null,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash,\n captureOwnerStack: captureOwnerStackServer,\n }\n\n const finalAttemptRSCPayload = await workUnitAsyncStorage.run(\n finalServerPayloadPrerenderStore,\n getRSCPayload,\n tree,\n ctx,\n isNotFound\n )\n\n const serverDynamicTracking = createDynamicTrackingState(\n false // isDebugDynamicAccesses\n )\n\n const finalServerPrerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: finalServerRenderController.signal,\n controller: finalServerReactController,\n // All caches we could read must already be filled so no tracking is necessary\n cacheSignal: null,\n dynamicTracking: serverDynamicTracking,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash,\n captureOwnerStack: captureOwnerStackServer,\n }\n\n const reactServerResult = await createReactServerPrerenderResult(\n prerenderAndAbortInSequentialTasks(\n async () => {\n const pendingPrerenderResult = workUnitAsyncStorage.run(\n // The store to scope\n finalServerPrerenderStore,\n // The function to run\n ComponentMod.prerender,\n // ... the arguments for the function to run\n finalAttemptRSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: (err: unknown) => {\n if (\n finalServerReactController.signal.aborted &&\n isPrerenderInterruptedError(err)\n ) {\n return err.digest\n }\n\n if (isReactLargeShellError(err)) {\n // TODO: Aggregate\n console.error(err)\n return undefined\n }\n\n return getDigestForWellKnownError(err)\n },\n signal: finalServerReactController.signal,\n }\n )\n\n // The listener to abort our own render controller must be added after\n // React has added its listener, to ensure that pending I/O is not\n // aborted/rejected too early.\n finalServerReactController.signal.addEventListener(\n 'abort',\n () => {\n finalServerRenderController.abort()\n },\n { once: true }\n )\n\n return pendingPrerenderResult\n },\n () => {\n finalServerReactController.abort()\n }\n )\n )\n\n const clientDynamicTracking = createDynamicTrackingState(\n false //isDebugDynamicAccesses\n )\n const finalClientReactController = new AbortController()\n const finalClientRenderController = new AbortController()\n\n const finalClientPrerenderStore: PrerenderStore = {\n type: 'prerender-client',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: finalClientRenderController.signal,\n controller: finalClientReactController,\n // No APIs require a cacheSignal through the workUnitStore during the HTML prerender\n cacheSignal: null,\n dynamicTracking: clientDynamicTracking,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache: null,\n hmrRefreshHash,\n captureOwnerStack: captureOwnerStackClient,\n }\n\n let dynamicValidation = createDynamicValidationState()\n\n try {\n const prerender = (\n require('react-dom/static') as typeof import('react-dom/static')\n ).prerender\n let { prelude: unprocessedPrelude } =\n await prerenderAndAbortInSequentialTasks(\n () => {\n const pendingFinalClientResult = workUnitAsyncStorage.run(\n finalClientPrerenderStore,\n prerender,\n ,\n {\n signal: finalClientReactController.signal,\n onError: (err: unknown, errorInfo: ErrorInfo) => {\n if (\n isPrerenderInterruptedError(err) ||\n finalClientReactController.signal.aborted\n ) {\n const componentStack = errorInfo.componentStack\n if (typeof componentStack === 'string') {\n trackAllowedDynamicAccess(\n workStore,\n componentStack,\n dynamicValidation,\n clientDynamicTracking\n )\n }\n return\n }\n\n if (isReactLargeShellError(err)) {\n // TODO: Aggregate\n console.error(err)\n return undefined\n }\n\n return getDigestForWellKnownError(err)\n },\n // We don't need bootstrap scripts in this prerender\n // bootstrapScripts: [bootstrapScript],\n }\n )\n\n // The listener to abort our own render controller must be added after\n // React has added its listener, to ensure that pending I/O is not\n // aborted/rejected too early.\n finalClientReactController.signal.addEventListener(\n 'abort',\n () => {\n finalClientRenderController.abort()\n },\n { once: true }\n )\n\n return pendingFinalClientResult\n },\n () => {\n finalClientReactController.abort()\n }\n )\n\n const { preludeIsEmpty } = await processPrelude(unprocessedPrelude)\n resolveValidation(\n \n )\n } catch (thrownValue) {\n // Even if the root errors we still want to report any cache components errors\n // that were discovered before the root errored.\n\n let loggingFunction = throwIfDisallowedDynamic.bind(\n null,\n workStore,\n PreludeState.Errored,\n dynamicValidation,\n serverDynamicTracking\n )\n\n if (process.env.NEXT_DEBUG_BUILD || process.env.__NEXT_VERBOSE_LOGGING) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n const originalLoggingFunction = loggingFunction\n loggingFunction = () => {\n console.error(\n 'During dynamic validation the root of the page errored. The next logged error is the thrown value. It may be a duplicate of errors reported during the normal development mode render.'\n )\n console.error(thrownValue)\n originalLoggingFunction()\n }\n }\n\n resolveValidation()\n }\n}\n\nasync function LogSafely({ fn }: { fn: () => unknown }) {\n try {\n await fn()\n } catch {}\n return null\n}\n\ntype PrerenderToStreamResult = {\n stream: ReadableStream\n digestErrorsMap: Map\n ssrErrors: Array\n dynamicAccess?: null | Array\n collectedRevalidate: number\n collectedExpire: number\n collectedStale: number\n collectedTags: null | string[]\n renderResumeDataCache?: RenderResumeDataCache\n}\n\n/**\n * Determines whether we should generate static flight data.\n */\nfunction shouldGenerateStaticFlightData(workStore: WorkStore): boolean {\n const { isStaticGeneration } = workStore\n if (!isStaticGeneration) return false\n\n return true\n}\n\nasync function prerenderToStream(\n req: BaseNextRequest,\n res: BaseNextResponse,\n ctx: AppRenderContext,\n metadata: AppPageRenderResultMetadata,\n tree: LoaderTree,\n fallbackRouteParams: FallbackRouteParams | null\n): Promise {\n // When prerendering formState is always null. We still include it\n // because some shared APIs expect a formState value and this is slightly\n // more explicit than making it an optional function argument\n const formState = null\n\n const {\n assetPrefix,\n getDynamicParamFromSegment,\n implicitTags,\n nonce,\n pagePath,\n renderOpts,\n workStore,\n } = ctx\n\n const {\n allowEmptyStaticShell = false,\n basePath,\n buildManifest,\n clientReferenceManifest,\n ComponentMod,\n crossOrigin,\n dev = false,\n experimental,\n isDebugDynamicAccesses,\n nextExport = false,\n onInstrumentationRequestError,\n page,\n reactMaxHeadersLength,\n subresourceIntegrityManifest,\n } = renderOpts\n\n assertClientReferenceManifest(clientReferenceManifest)\n\n const rootParams = getRootParams(tree, getDynamicParamFromSegment)\n\n const { ServerInsertedHTMLProvider, renderServerInsertedHTML } =\n createServerInsertedHTML()\n const getServerInsertedMetadata = createServerInsertedMetadata(nonce)\n\n const tracingMetadata = getTracedMetadata(\n getTracer().getTracePropagationData(),\n experimental.clientTraceMetadata\n )\n\n const polyfills: JSX.IntrinsicElements['script'][] =\n buildManifest.polyfillFiles\n .filter(\n (polyfill) =>\n polyfill.endsWith('.js') && !polyfill.endsWith('.module.js')\n )\n .map((polyfill) => ({\n src: `${assetPrefix}/_next/${polyfill}${getAssetQueryString(\n ctx,\n false\n )}`,\n integrity: subresourceIntegrityManifest?.[polyfill],\n crossOrigin,\n noModule: true,\n nonce,\n }))\n\n const [preinitScripts, bootstrapScript] = getRequiredScripts(\n buildManifest,\n // Why is assetPrefix optional on renderOpts?\n // @TODO make it default empty string on renderOpts and get rid of it from ctx\n assetPrefix,\n crossOrigin,\n subresourceIntegrityManifest,\n getAssetQueryString(ctx, true),\n nonce,\n page\n )\n\n const reactServerErrorsByDigest: Map = new Map()\n // We don't report errors during prerendering through our instrumentation hooks\n const silenceLogger = !!experimental.isRoutePPREnabled\n function onHTMLRenderRSCError(err: DigestedError) {\n return onInstrumentationRequestError?.(\n err,\n req,\n createErrorContext(ctx, 'react-server-components')\n )\n }\n const serverComponentsErrorHandler = createHTMLReactServerErrorHandler(\n dev,\n nextExport,\n reactServerErrorsByDigest,\n silenceLogger,\n onHTMLRenderRSCError\n )\n\n function onHTMLRenderSSRError(err: DigestedError) {\n return onInstrumentationRequestError?.(\n err,\n req,\n createErrorContext(ctx, 'server-rendering')\n )\n }\n const allCapturedErrors: Array = []\n const htmlRendererErrorHandler = createHTMLErrorHandler(\n dev,\n nextExport,\n reactServerErrorsByDigest,\n allCapturedErrors,\n silenceLogger,\n onHTMLRenderSSRError\n )\n\n let reactServerPrerenderResult: null | ReactServerPrerenderResult = null\n const setMetadataHeader = (name: string) => {\n metadata.headers ??= {}\n metadata.headers[name] = res.getHeader(name)\n }\n const setHeader = (name: string, value: string | string[]) => {\n res.setHeader(name, value)\n setMetadataHeader(name)\n return res\n }\n const appendHeader = (name: string, value: string | string[]) => {\n if (Array.isArray(value)) {\n value.forEach((item) => {\n res.appendHeader(name, item)\n })\n } else {\n res.appendHeader(name, value)\n }\n setMetadataHeader(name)\n }\n\n const selectStaleTime = createSelectStaleTime(experimental)\n\n let prerenderStore: PrerenderStore | null = null\n\n try {\n if (experimental.cacheComponents) {\n /**\n * cacheComponents with PPR\n *\n * The general approach is to render the RSC stream first allowing any cache reads to resolve.\n * Once we have settled all cache reads we restart the render and abort after a single Task.\n *\n * Unlike with the non PPR case we can't synchronously abort the render when a dynamic API is used\n * during the initial render because we need to ensure all caches can be filled as part of the initial Task\n * and a synchronous abort might prevent us from filling all caches.\n *\n * Once the render is complete we allow the SSR render to finish and use a combination of the postponed state\n * and the reactServerIsDynamic value to determine how to treat the resulting render\n */\n\n // The prerender controller represents the lifetime of the prerender. It\n // will be aborted when a task is complete or a synchronously aborting API\n // is called. Notably, during prospective prerenders, this does not\n // actually terminate the prerender itself, which will continue until all\n // caches are filled.\n const initialServerPrerenderController = new AbortController()\n\n // This controller is used to abort the React prerender.\n const initialServerReactController = new AbortController()\n\n // This controller represents the lifetime of the React prerender. Its\n // signal can be used for any I/O operation to abort the I/O and/or to\n // reject, when prerendering aborts. This includes our own hanging\n // promises for accessing request data, and for fetch calls. It might be\n // replaced in the future by React.cacheSignal(). It's aborted after the\n // React controller, so that no pending I/O can register abort listeners\n // that are called before React's abort listener is called. This ensures\n // that pending I/O is not rejected too early when aborting the prerender.\n // Notably, during the prospective prerender, it is different from the\n // prerender controller because we don't want to end the React prerender\n // until all caches are filled.\n const initialServerRenderController = new AbortController()\n\n // The cacheSignal helps us track whether caches are still filling or we are ready\n // to cut the render off.\n const cacheSignal = new CacheSignal()\n\n let resumeDataCache: RenderResumeDataCache | PrerenderResumeDataCache\n let renderResumeDataCache: RenderResumeDataCache | null = null\n let prerenderResumeDataCache: PrerenderResumeDataCache | null = null\n\n if (renderOpts.renderResumeDataCache) {\n // If a prefilled immutable render resume data cache is provided, e.g.\n // when prerendering an optional fallback shell after having prerendered\n // pages with defined params, we use this instead of a prerender resume\n // data cache.\n resumeDataCache = renderResumeDataCache =\n renderOpts.renderResumeDataCache\n } else {\n // Otherwise we create a new mutable prerender resume data cache.\n resumeDataCache = prerenderResumeDataCache =\n createPrerenderResumeDataCache()\n }\n\n const initialServerPayloadPrerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n // While this render signal isn't going to be used to abort a React render while getting the RSC payload\n // various request data APIs bind to this controller to reject after completion.\n renderSignal: initialServerRenderController.signal,\n // When we generate the RSC payload we might abort this controller due to sync IO\n // but we don't actually care about sync IO in this phase so we use a throw away controller\n // that isn't connected to anything\n controller: new AbortController(),\n // During the initial prerender we need to track all cache reads to ensure\n // we render long enough to fill every cache it is possible to visit during\n // the final prerender.\n cacheSignal,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined, // Not available in production.\n }\n\n // We're not going to use the result of this render because the only time it could be used\n // is if it completes in a microtask and that's likely very rare for any non-trivial app\n const initialServerPayload = await workUnitAsyncStorage.run(\n initialServerPayloadPrerenderStore,\n getRSCPayload,\n tree,\n ctx,\n res.statusCode === 404\n )\n\n const initialServerPrerenderStore: PrerenderStore = (prerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: initialServerRenderController.signal,\n controller: initialServerPrerenderController,\n // During the initial prerender we need to track all cache reads to ensure\n // we render long enough to fill every cache it is possible to visit during\n // the final prerender.\n cacheSignal,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined, // Not available in production.\n })\n\n const pendingInitialServerResult = workUnitAsyncStorage.run(\n initialServerPrerenderStore,\n ComponentMod.prerender,\n initialServerPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: (err) => {\n const digest = getDigestForWellKnownError(err)\n\n if (digest) {\n return digest\n }\n\n if (isReactLargeShellError(err)) {\n // TODO: Aggregate\n console.error(err)\n return undefined\n }\n\n if (initialServerPrerenderController.signal.aborted) {\n // The render aborted before this error was handled which indicates\n // the error is caused by unfinished components within the render\n return\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n },\n // we don't care to track postpones during the prospective render because we need\n // to always do a final render anyway\n onPostpone: undefined,\n // We don't want to stop rendering until the cacheSignal is complete so we pass\n // a different signal to this render call than is used by dynamic APIs to signify\n // transitioning out of the prerender environment\n signal: initialServerReactController.signal,\n }\n )\n\n // The listener to abort our own render controller must be added after\n // React has added its listener, to ensure that pending I/O is not\n // aborted/rejected too early.\n initialServerReactController.signal.addEventListener(\n 'abort',\n () => {\n initialServerRenderController.abort()\n },\n { once: true }\n )\n\n // Wait for all caches to be finished filling and for async imports to resolve\n trackPendingModules(cacheSignal)\n await cacheSignal.cacheReady()\n\n initialServerReactController.abort()\n\n // We don't need to continue the prerender process if we already\n // detected invalid dynamic usage in the initial prerender phase.\n if (workStore.invalidDynamicUsageError) {\n logDisallowedDynamicError(workStore, workStore.invalidDynamicUsageError)\n throw new StaticGenBailoutError()\n }\n\n let initialServerResult\n try {\n initialServerResult = await createReactServerPrerenderResult(\n pendingInitialServerResult\n )\n } catch (err) {\n if (\n initialServerReactController.signal.aborted ||\n initialServerPrerenderController.signal.aborted\n ) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n }\n\n if (initialServerResult) {\n const initialClientPrerenderController = new AbortController()\n const initialClientReactController = new AbortController()\n const initialClientRenderController = new AbortController()\n\n const initialClientPrerenderStore: PrerenderStore = {\n type: 'prerender-client',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: initialClientRenderController.signal,\n controller: initialClientPrerenderController,\n // For HTML Generation the only cache tracked activity\n // is module loading, which has it's own cache signal\n cacheSignal: null,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined, // Not available in production.\n }\n\n const prerender = (\n require('react-dom/static') as typeof import('react-dom/static')\n ).prerender\n const pendingInitialClientResult = workUnitAsyncStorage.run(\n initialClientPrerenderStore,\n prerender,\n ,\n {\n signal: initialClientReactController.signal,\n onError: (err) => {\n const digest = getDigestForWellKnownError(err)\n\n if (digest) {\n return digest\n }\n\n if (isReactLargeShellError(err)) {\n // TODO: Aggregate\n console.error(err)\n return undefined\n }\n\n if (initialClientReactController.signal.aborted) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n },\n bootstrapScripts: [bootstrapScript],\n }\n )\n\n // The listener to abort our own render controller must be added after\n // React has added its listener, to ensure that pending I/O is not\n // aborted/rejected too early.\n initialClientReactController.signal.addEventListener(\n 'abort',\n () => {\n initialClientRenderController.abort()\n },\n { once: true }\n )\n\n pendingInitialClientResult.catch((err) => {\n if (\n initialClientReactController.signal.aborted ||\n isPrerenderInterruptedError(err)\n ) {\n // These are expected errors that might error the prerender. we ignore them.\n } else if (\n process.env.NEXT_DEBUG_BUILD ||\n process.env.__NEXT_VERBOSE_LOGGING\n ) {\n // We don't normally log these errors because we are going to retry anyway but\n // it can be useful for debugging Next.js itself to get visibility here when needed\n printDebugThrownValueForProspectiveRender(err, workStore.route)\n }\n })\n\n // This is mostly needed for dynamic `import()`s in client components.\n // Promises passed to client were already awaited above (assuming that they came from cached functions)\n trackPendingModules(cacheSignal)\n await cacheSignal.cacheReady()\n initialClientReactController.abort()\n }\n\n const finalServerReactController = new AbortController()\n const finalServerRenderController = new AbortController()\n\n const finalServerPayloadPrerenderStore: PrerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n // While this render signal isn't going to be used to abort a React render while getting the RSC payload\n // various request data APIs bind to this controller to reject after completion.\n renderSignal: finalServerRenderController.signal,\n // When we generate the RSC payload we might abort this controller due to sync IO\n // but we don't actually care about sync IO in this phase so we use a throw away controller\n // that isn't connected to anything\n controller: new AbortController(),\n // All caches we could read must already be filled so no tracking is necessary\n cacheSignal: null,\n dynamicTracking: null,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined, // Not available in production.\n }\n\n const finalAttemptRSCPayload = await workUnitAsyncStorage.run(\n finalServerPayloadPrerenderStore,\n getRSCPayload,\n tree,\n ctx,\n res.statusCode === 404\n )\n\n const serverDynamicTracking = createDynamicTrackingState(\n isDebugDynamicAccesses\n )\n let serverIsDynamic = false\n\n const finalServerPrerenderStore: PrerenderStore = (prerenderStore = {\n type: 'prerender',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: finalServerRenderController.signal,\n controller: finalServerReactController,\n // All caches we could read must already be filled so no tracking is necessary\n cacheSignal: null,\n dynamicTracking: serverDynamicTracking,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined, // Not available in production.\n })\n\n let prerenderIsPending = true\n const reactServerResult = (reactServerPrerenderResult =\n await createReactServerPrerenderResult(\n prerenderAndAbortInSequentialTasks(\n async () => {\n const pendingPrerenderResult = workUnitAsyncStorage.run(\n // The store to scope\n finalServerPrerenderStore,\n // The function to run\n ComponentMod.prerender,\n // ... the arguments for the function to run\n finalAttemptRSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: (err: unknown) => {\n return serverComponentsErrorHandler(err)\n },\n signal: finalServerReactController.signal,\n }\n )\n\n // The listener to abort our own render controller must be added\n // after React has added its listener, to ensure that pending I/O\n // is not aborted/rejected too early.\n finalServerReactController.signal.addEventListener(\n 'abort',\n () => {\n finalServerRenderController.abort()\n },\n { once: true }\n )\n\n const prerenderResult = await pendingPrerenderResult\n prerenderIsPending = false\n\n return prerenderResult\n },\n () => {\n if (finalServerReactController.signal.aborted) {\n // If the server controller is already aborted we must have called something\n // that required aborting the prerender synchronously such as with new Date()\n serverIsDynamic = true\n return\n }\n\n if (prerenderIsPending) {\n // If prerenderIsPending then we have blocked for longer than a Task and we assume\n // there is something unfinished.\n serverIsDynamic = true\n }\n\n finalServerReactController.abort()\n }\n )\n ))\n\n const clientDynamicTracking = createDynamicTrackingState(\n isDebugDynamicAccesses\n )\n\n const finalClientReactController = new AbortController()\n const finalClientRenderController = new AbortController()\n\n const finalClientPrerenderStore: PrerenderStore = {\n type: 'prerender-client',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n renderSignal: finalClientRenderController.signal,\n controller: finalClientReactController,\n // No APIs require a cacheSignal through the workUnitStore during the HTML prerender\n cacheSignal: null,\n dynamicTracking: clientDynamicTracking,\n allowEmptyStaticShell,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n renderResumeDataCache,\n hmrRefreshHash: undefined,\n captureOwnerStack: undefined, // Not available in production.\n }\n\n let dynamicValidation = createDynamicValidationState()\n\n const prerender = (\n require('react-dom/static') as typeof import('react-dom/static')\n ).prerender\n let { prelude: unprocessedPrelude, postponed } =\n await prerenderAndAbortInSequentialTasks(\n () => {\n const pendingFinalClientResult = workUnitAsyncStorage.run(\n finalClientPrerenderStore,\n prerender,\n ,\n {\n signal: finalClientReactController.signal,\n onError: (err: unknown, errorInfo: ErrorInfo) => {\n if (\n isPrerenderInterruptedError(err) ||\n finalClientReactController.signal.aborted\n ) {\n const componentStack: string | undefined = (\n errorInfo as any\n ).componentStack\n if (typeof componentStack === 'string') {\n trackAllowedDynamicAccess(\n workStore,\n componentStack,\n dynamicValidation,\n clientDynamicTracking\n )\n }\n return\n }\n\n return htmlRendererErrorHandler(err, errorInfo)\n },\n onHeaders: (headers: Headers) => {\n headers.forEach((value, key) => {\n appendHeader(key, value)\n })\n },\n maxHeadersLength: reactMaxHeadersLength,\n bootstrapScripts: [bootstrapScript],\n }\n )\n\n // The listener to abort our own render controller must be added\n // after React has added its listener, to ensure that pending I/O is\n // not aborted/rejected too early.\n finalClientReactController.signal.addEventListener(\n 'abort',\n () => {\n finalClientRenderController.abort()\n },\n { once: true }\n )\n\n return pendingFinalClientResult\n },\n () => {\n finalClientReactController.abort()\n }\n )\n\n const { prelude, preludeIsEmpty } =\n await processPrelude(unprocessedPrelude)\n\n // If we've disabled throwing on empty static shell, then we don't need to\n // track any dynamic access that occurs above the suspense boundary because\n // we'll do so in the route shell.\n if (!allowEmptyStaticShell) {\n throwIfDisallowedDynamic(\n workStore,\n preludeIsEmpty ? PreludeState.Empty : PreludeState.Full,\n dynamicValidation,\n serverDynamicTracking\n )\n }\n\n const getServerInsertedHTML = makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: allCapturedErrors,\n basePath,\n tracingMetadata: tracingMetadata,\n })\n\n const flightData = await streamToBuffer(reactServerResult.asStream())\n metadata.flightData = flightData\n metadata.segmentData = await collectSegmentData(\n flightData,\n finalServerPrerenderStore,\n ComponentMod,\n renderOpts\n )\n\n // If there are fallback route params, the RSC data is inherently dynamic\n // today because it's encoded into the flight router state. Until we can\n // move the fallback route params out of the flight router state, we need\n // to always perform a dynamic resume after the static prerender.\n const hasFallbackRouteParams =\n fallbackRouteParams && fallbackRouteParams.size > 0\n\n if (serverIsDynamic || hasFallbackRouteParams) {\n // Dynamic case\n // We will always need to perform a \"resume\" render of some kind when this route is accessed\n // because the RSC data itself is dynamic. We determine if there are any HTML holes or not\n // but generally this is a \"partial\" prerender in that there will be a per-request compute\n // concatenated to the static shell.\n if (postponed != null) {\n // Dynamic HTML case\n metadata.postponed = await getDynamicHTMLPostponedState(\n postponed,\n preludeIsEmpty\n ? DynamicHTMLPreludeState.Empty\n : DynamicHTMLPreludeState.Full,\n fallbackRouteParams,\n resumeDataCache\n )\n } else {\n // Dynamic Data case\n metadata.postponed =\n await getDynamicDataPostponedState(resumeDataCache)\n }\n reactServerResult.consume()\n return {\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueDynamicPrerender(prelude, {\n getServerInsertedHTML,\n getServerInsertedMetadata,\n }),\n dynamicAccess: consumeDynamicAccess(\n serverDynamicTracking,\n clientDynamicTracking\n ),\n // TODO: Should this include the SSR pass?\n collectedRevalidate: finalServerPrerenderStore.revalidate,\n collectedExpire: finalServerPrerenderStore.expire,\n collectedStale: selectStaleTime(finalServerPrerenderStore.stale),\n collectedTags: finalServerPrerenderStore.tags,\n renderResumeDataCache: createRenderResumeDataCache(resumeDataCache),\n }\n } else {\n // Static case\n // We will not perform resumption per request. The result can be served statically to the requestor\n // and if there was anything dynamic it will only be rendered in the browser.\n if (workStore.forceDynamic) {\n throw new StaticGenBailoutError(\n 'Invariant: a Page with `dynamic = \"force-dynamic\"` did not trigger the dynamic pathway. This is a bug in Next.js'\n )\n }\n\n let htmlStream = prelude\n if (postponed != null) {\n // We postponed but nothing dynamic was used. We resume the render now and immediately abort it\n // so we can set all the postponed boundaries to client render mode before we store the HTML response\n const resume = (\n require('react-dom/server') as typeof import('react-dom/server')\n ).resume\n\n // We don't actually want to render anything so we just pass a stream\n // that never resolves. The resume call is going to abort immediately anyway\n const foreverStream = new ReadableStream()\n\n const resumeStream = await resume(\n {}}\n clientReferenceManifest={clientReferenceManifest}\n ServerInsertedHTMLProvider={ServerInsertedHTMLProvider}\n nonce={nonce}\n />,\n JSON.parse(JSON.stringify(postponed)),\n {\n signal: createRenderInBrowserAbortSignal(),\n onError: htmlRendererErrorHandler,\n nonce,\n }\n )\n\n // First we write everything from the prerender, then we write everything from the aborted resume render\n htmlStream = chainStreams(prelude, resumeStream)\n }\n\n return {\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueStaticPrerender(htmlStream, {\n inlinedDataStream: createInlinedDataReadableStream(\n reactServerResult.consumeAsStream(),\n nonce,\n formState\n ),\n getServerInsertedHTML,\n getServerInsertedMetadata,\n isBuildTimePrerendering:\n ctx.workStore.isBuildTimePrerendering === true,\n buildId: ctx.workStore.buildId,\n }),\n dynamicAccess: consumeDynamicAccess(\n serverDynamicTracking,\n clientDynamicTracking\n ),\n // TODO: Should this include the SSR pass?\n collectedRevalidate: finalServerPrerenderStore.revalidate,\n collectedExpire: finalServerPrerenderStore.expire,\n collectedStale: selectStaleTime(finalServerPrerenderStore.stale),\n collectedTags: finalServerPrerenderStore.tags,\n renderResumeDataCache: createRenderResumeDataCache(resumeDataCache),\n }\n }\n } else if (experimental.isRoutePPREnabled) {\n // We're statically generating with PPR and need to do dynamic tracking\n let dynamicTracking = createDynamicTrackingState(isDebugDynamicAccesses)\n\n const prerenderResumeDataCache = createPrerenderResumeDataCache()\n const reactServerPrerenderStore: PrerenderStore = (prerenderStore = {\n type: 'prerender-ppr',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n dynamicTracking,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n })\n const RSCPayload = await workUnitAsyncStorage.run(\n reactServerPrerenderStore,\n getRSCPayload,\n tree,\n ctx,\n res.statusCode === 404\n )\n const reactServerResult = (reactServerPrerenderResult =\n await createReactServerPrerenderResultFromRender(\n workUnitAsyncStorage.run(\n reactServerPrerenderStore,\n ComponentMod.renderToReadableStream,\n // ... the arguments for the function to run\n RSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: serverComponentsErrorHandler,\n }\n )\n ))\n\n const ssrPrerenderStore: PrerenderStore = {\n type: 'prerender-ppr',\n phase: 'render',\n rootParams,\n fallbackRouteParams,\n implicitTags,\n dynamicTracking,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n prerenderResumeDataCache,\n }\n const prerender = (\n require('react-dom/static') as typeof import('react-dom/static')\n ).prerender\n const { prelude: unprocessedPrelude, postponed } =\n await workUnitAsyncStorage.run(\n ssrPrerenderStore,\n prerender,\n ,\n {\n onError: htmlRendererErrorHandler,\n onHeaders: (headers: Headers) => {\n headers.forEach((value, key) => {\n appendHeader(key, value)\n })\n },\n maxHeadersLength: reactMaxHeadersLength,\n bootstrapScripts: [bootstrapScript],\n }\n )\n const getServerInsertedHTML = makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: allCapturedErrors,\n basePath,\n tracingMetadata: tracingMetadata,\n })\n\n // After awaiting here we've waited for the entire RSC render to complete. Crucially this means\n // that when we detect whether we've used dynamic APIs below we know we'll have picked up even\n // parts of the React Server render that might not be used in the SSR render.\n const flightData = await streamToBuffer(reactServerResult.asStream())\n\n if (shouldGenerateStaticFlightData(workStore)) {\n metadata.flightData = flightData\n metadata.segmentData = await collectSegmentData(\n flightData,\n ssrPrerenderStore,\n ComponentMod,\n renderOpts\n )\n }\n\n const { prelude, preludeIsEmpty } =\n await processPrelude(unprocessedPrelude)\n\n /**\n * When prerendering there are three outcomes to consider\n *\n * Dynamic HTML: The prerender has dynamic holes (caused by using Next.js Dynamic Rendering APIs)\n * We will need to resume this result when requests are handled and we don't include\n * any server inserted HTML or inlined flight data in the static HTML\n *\n * Dynamic Data: The prerender has no dynamic holes but dynamic APIs were used. We will not\n * resume this render when requests are handled but we will generate new inlined\n * flight data since it is dynamic and differences may end up reconciling on the client\n *\n * Static: The prerender has no dynamic holes and no dynamic APIs were used. We statically encode\n * all server inserted HTML and flight data\n */\n // First we check if we have any dynamic holes in our HTML prerender\n if (accessedDynamicData(dynamicTracking.dynamicAccesses)) {\n if (postponed != null) {\n // Dynamic HTML case.\n metadata.postponed = await getDynamicHTMLPostponedState(\n postponed,\n preludeIsEmpty\n ? DynamicHTMLPreludeState.Empty\n : DynamicHTMLPreludeState.Full,\n fallbackRouteParams,\n prerenderResumeDataCache\n )\n } else {\n // Dynamic Data case.\n metadata.postponed = await getDynamicDataPostponedState(\n prerenderResumeDataCache\n )\n }\n // Regardless of whether this is the Dynamic HTML or Dynamic Data case we need to ensure we include\n // server inserted html in the static response because the html that is part of the prerender may depend on it\n // It is possible in the set of stream transforms for Dynamic HTML vs Dynamic Data may differ but currently both states\n // require the same set so we unify the code path here\n reactServerResult.consume()\n return {\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueDynamicPrerender(prelude, {\n getServerInsertedHTML,\n getServerInsertedMetadata,\n }),\n dynamicAccess: dynamicTracking.dynamicAccesses,\n // TODO: Should this include the SSR pass?\n collectedRevalidate: reactServerPrerenderStore.revalidate,\n collectedExpire: reactServerPrerenderStore.expire,\n collectedStale: selectStaleTime(reactServerPrerenderStore.stale),\n collectedTags: reactServerPrerenderStore.tags,\n }\n } else if (fallbackRouteParams && fallbackRouteParams.size > 0) {\n // Rendering the fallback case.\n metadata.postponed = await getDynamicDataPostponedState(\n prerenderResumeDataCache\n )\n\n return {\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueDynamicPrerender(prelude, {\n getServerInsertedHTML,\n getServerInsertedMetadata,\n }),\n dynamicAccess: dynamicTracking.dynamicAccesses,\n // TODO: Should this include the SSR pass?\n collectedRevalidate: reactServerPrerenderStore.revalidate,\n collectedExpire: reactServerPrerenderStore.expire,\n collectedStale: selectStaleTime(reactServerPrerenderStore.stale),\n collectedTags: reactServerPrerenderStore.tags,\n }\n } else {\n // Static case\n // We still have not used any dynamic APIs. At this point we can produce an entirely static prerender response\n if (workStore.forceDynamic) {\n throw new StaticGenBailoutError(\n 'Invariant: a Page with `dynamic = \"force-dynamic\"` did not trigger the dynamic pathway. This is a bug in Next.js'\n )\n }\n\n let htmlStream = prelude\n if (postponed != null) {\n // We postponed but nothing dynamic was used. We resume the render now and immediately abort it\n // so we can set all the postponed boundaries to client render mode before we store the HTML response\n const resume = (\n require('react-dom/server') as typeof import('react-dom/server')\n ).resume\n\n // We don't actually want to render anything so we just pass a stream\n // that never resolves. The resume call is going to abort immediately anyway\n const foreverStream = new ReadableStream()\n\n const resumeStream = await resume(\n {}}\n clientReferenceManifest={clientReferenceManifest}\n ServerInsertedHTMLProvider={ServerInsertedHTMLProvider}\n nonce={nonce}\n />,\n JSON.parse(JSON.stringify(postponed)),\n {\n signal: createRenderInBrowserAbortSignal(),\n onError: htmlRendererErrorHandler,\n nonce,\n }\n )\n\n // First we write everything from the prerender, then we write everything from the aborted resume render\n htmlStream = chainStreams(prelude, resumeStream)\n }\n\n return {\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueStaticPrerender(htmlStream, {\n inlinedDataStream: createInlinedDataReadableStream(\n reactServerResult.consumeAsStream(),\n nonce,\n formState\n ),\n getServerInsertedHTML,\n getServerInsertedMetadata,\n isBuildTimePrerendering:\n ctx.workStore.isBuildTimePrerendering === true,\n buildId: ctx.workStore.buildId,\n }),\n dynamicAccess: dynamicTracking.dynamicAccesses,\n // TODO: Should this include the SSR pass?\n collectedRevalidate: reactServerPrerenderStore.revalidate,\n collectedExpire: reactServerPrerenderStore.expire,\n collectedStale: selectStaleTime(reactServerPrerenderStore.stale),\n collectedTags: reactServerPrerenderStore.tags,\n }\n }\n } else {\n const prerenderLegacyStore: PrerenderStore = (prerenderStore = {\n type: 'prerender-legacy',\n phase: 'render',\n rootParams,\n implicitTags,\n revalidate: INFINITE_CACHE,\n expire: INFINITE_CACHE,\n stale: INFINITE_CACHE,\n tags: [...implicitTags.tags],\n })\n // This is a regular static generation. We don't do dynamic tracking because we rely on\n // the old-school dynamic error handling to bail out of static generation\n const RSCPayload = await workUnitAsyncStorage.run(\n prerenderLegacyStore,\n getRSCPayload,\n tree,\n ctx,\n res.statusCode === 404\n )\n\n const reactServerResult = (reactServerPrerenderResult =\n await createReactServerPrerenderResultFromRender(\n workUnitAsyncStorage.run(\n prerenderLegacyStore,\n ComponentMod.renderToReadableStream,\n RSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: serverComponentsErrorHandler,\n }\n )\n ))\n\n const renderToReadableStream = (\n require('react-dom/server') as typeof import('react-dom/server')\n ).renderToReadableStream\n const htmlStream = await workUnitAsyncStorage.run(\n prerenderLegacyStore,\n renderToReadableStream,\n ,\n {\n onError: htmlRendererErrorHandler,\n nonce,\n bootstrapScripts: [bootstrapScript],\n }\n )\n\n if (shouldGenerateStaticFlightData(workStore)) {\n const flightData = await streamToBuffer(reactServerResult.asStream())\n metadata.flightData = flightData\n metadata.segmentData = await collectSegmentData(\n flightData,\n prerenderLegacyStore,\n ComponentMod,\n renderOpts\n )\n }\n\n const getServerInsertedHTML = makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: allCapturedErrors,\n basePath,\n tracingMetadata: tracingMetadata,\n })\n return {\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueFizzStream(htmlStream, {\n inlinedDataStream: createInlinedDataReadableStream(\n reactServerResult.consumeAsStream(),\n nonce,\n formState\n ),\n isStaticGeneration: true,\n isBuildTimePrerendering:\n ctx.workStore.isBuildTimePrerendering === true,\n buildId: ctx.workStore.buildId,\n getServerInsertedHTML,\n getServerInsertedMetadata,\n }),\n // TODO: Should this include the SSR pass?\n collectedRevalidate: prerenderLegacyStore.revalidate,\n collectedExpire: prerenderLegacyStore.expire,\n collectedStale: selectStaleTime(prerenderLegacyStore.stale),\n collectedTags: prerenderLegacyStore.tags,\n }\n }\n } catch (err) {\n if (\n isStaticGenBailoutError(err) ||\n (typeof err === 'object' &&\n err !== null &&\n 'message' in err &&\n typeof err.message === 'string' &&\n err.message.includes(\n 'https://nextjs.org/docs/advanced-features/static-html-export'\n ))\n ) {\n // Ensure that \"next dev\" prints the red error overlay\n throw err\n }\n\n // If this is a static generation error, we need to throw it so that it\n // can be handled by the caller if we're in static generation mode.\n if (isDynamicServerError(err)) {\n throw err\n }\n\n // If a bailout made it to this point, it means it wasn't wrapped inside\n // a suspense boundary.\n const shouldBailoutToCSR = isBailoutToCSRError(err)\n if (shouldBailoutToCSR) {\n const stack = getStackWithoutErrorMessage(err)\n error(\n `${err.reason} should be wrapped in a suspense boundary at page \"${pagePath}\". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout\\n${stack}`\n )\n\n throw err\n }\n\n // If we errored when we did not have an RSC stream to read from. This is\n // not just a render error, we need to throw early.\n if (reactServerPrerenderResult === null) {\n throw err\n }\n\n let errorType: MetadataErrorType | 'redirect' | undefined\n\n if (isHTTPAccessFallbackError(err)) {\n res.statusCode = getAccessFallbackHTTPStatus(err)\n metadata.statusCode = res.statusCode\n errorType = getAccessFallbackErrorTypeByStatus(res.statusCode)\n } else if (isRedirectError(err)) {\n errorType = 'redirect'\n res.statusCode = getRedirectStatusCodeFromError(err)\n metadata.statusCode = res.statusCode\n\n const redirectUrl = addPathPrefix(getURLFromRedirectError(err), basePath)\n\n setHeader('location', redirectUrl)\n } else if (!shouldBailoutToCSR) {\n res.statusCode = 500\n metadata.statusCode = res.statusCode\n }\n\n const [errorPreinitScripts, errorBootstrapScript] = getRequiredScripts(\n buildManifest,\n assetPrefix,\n crossOrigin,\n subresourceIntegrityManifest,\n getAssetQueryString(ctx, false),\n nonce,\n '/_not-found/page'\n )\n\n const prerenderLegacyStore: PrerenderStore = (prerenderStore = {\n type: 'prerender-legacy',\n phase: 'render',\n rootParams,\n implicitTags: implicitTags,\n revalidate:\n typeof prerenderStore?.revalidate !== 'undefined'\n ? prerenderStore.revalidate\n : INFINITE_CACHE,\n expire:\n typeof prerenderStore?.expire !== 'undefined'\n ? prerenderStore.expire\n : INFINITE_CACHE,\n stale:\n typeof prerenderStore?.stale !== 'undefined'\n ? prerenderStore.stale\n : INFINITE_CACHE,\n tags: [...(prerenderStore?.tags || implicitTags.tags)],\n })\n const errorRSCPayload = await workUnitAsyncStorage.run(\n prerenderLegacyStore,\n getErrorRSCPayload,\n tree,\n ctx,\n reactServerErrorsByDigest.has((err as any).digest) ? undefined : err,\n errorType\n )\n\n const errorServerStream = workUnitAsyncStorage.run(\n prerenderLegacyStore,\n ComponentMod.renderToReadableStream,\n errorRSCPayload,\n clientReferenceManifest.clientModules,\n {\n filterStackFrame,\n onError: serverComponentsErrorHandler,\n }\n )\n\n try {\n // TODO we should use the same prerender semantics that we initially rendered\n // with in this case too. The only reason why this is ok atm is because it's essentially\n // an empty page and no user code runs.\n const fizzStream = await workUnitAsyncStorage.run(\n prerenderLegacyStore,\n renderToInitialFizzStream,\n {\n ReactDOMServer:\n require('react-dom/server') as typeof import('react-dom/server'),\n element: (\n \n ),\n streamOptions: {\n nonce,\n // Include hydration scripts in the HTML\n bootstrapScripts: [errorBootstrapScript],\n formState,\n },\n }\n )\n\n if (shouldGenerateStaticFlightData(workStore)) {\n const flightData = await streamToBuffer(\n reactServerPrerenderResult.asStream()\n )\n metadata.flightData = flightData\n metadata.segmentData = await collectSegmentData(\n flightData,\n prerenderLegacyStore,\n ComponentMod,\n renderOpts\n )\n }\n\n // This is intentionally using the readable datastream from the main\n // render rather than the flight data from the error page render\n const flightStream = reactServerPrerenderResult.consumeAsStream()\n\n return {\n // Returning the error that was thrown so it can be used to handle\n // the response in the caller.\n digestErrorsMap: reactServerErrorsByDigest,\n ssrErrors: allCapturedErrors,\n stream: await continueFizzStream(fizzStream, {\n inlinedDataStream: createInlinedDataReadableStream(\n flightStream,\n nonce,\n formState\n ),\n isStaticGeneration: true,\n isBuildTimePrerendering:\n ctx.workStore.isBuildTimePrerendering === true,\n buildId: ctx.workStore.buildId,\n getServerInsertedHTML: makeGetServerInsertedHTML({\n polyfills,\n renderServerInsertedHTML,\n serverCapturedErrors: [],\n basePath,\n tracingMetadata: tracingMetadata,\n }),\n getServerInsertedMetadata,\n validateRootLayout: dev,\n }),\n dynamicAccess: null,\n collectedRevalidate:\n prerenderStore !== null ? prerenderStore.revalidate : INFINITE_CACHE,\n collectedExpire:\n prerenderStore !== null ? prerenderStore.expire : INFINITE_CACHE,\n collectedStale: selectStaleTime(\n prerenderStore !== null ? prerenderStore.stale : INFINITE_CACHE\n ),\n collectedTags: prerenderStore !== null ? prerenderStore.tags : null,\n }\n } catch (finalErr: any) {\n if (\n process.env.NODE_ENV === 'development' &&\n isHTTPAccessFallbackError(finalErr)\n ) {\n const { bailOnRootNotFound } =\n require('../../client/components/dev-root-http-access-fallback-boundary') as typeof import('../../client/components/dev-root-http-access-fallback-boundary')\n bailOnRootNotFound()\n }\n throw finalErr\n }\n }\n}\n\nconst getGlobalErrorStyles = async (\n tree: LoaderTree,\n ctx: AppRenderContext\n): Promise<{\n GlobalError: GlobalErrorComponent\n styles: React.ReactNode | undefined\n}> => {\n const {\n modules: { 'global-error': globalErrorModule },\n } = parseLoaderTree(tree)\n\n const GlobalErrorComponent: GlobalErrorComponent =\n ctx.componentMod.GlobalError\n let globalErrorStyles\n if (globalErrorModule) {\n const [, styles] = await createComponentStylesAndScripts({\n ctx,\n filePath: globalErrorModule[1],\n getComponent: globalErrorModule[0],\n injectedCSS: new Set(),\n injectedJS: new Set(),\n })\n globalErrorStyles = styles\n }\n if (ctx.renderOpts.dev) {\n const dir =\n (process.env.NEXT_RUNTIME === 'edge'\n ? process.env.__NEXT_EDGE_PROJECT_DIR\n : ctx.renderOpts.dir) || ''\n\n const globalErrorModulePath = normalizeConventionFilePath(\n dir,\n globalErrorModule?.[1]\n )\n if (ctx.renderOpts.devtoolSegmentExplorer && globalErrorModulePath) {\n const SegmentViewNode = ctx.componentMod.SegmentViewNode\n globalErrorStyles = (\n // This will be rendered next to GlobalError component under ErrorBoundary,\n // it requires a key to avoid React warning about duplicate keys.\n \n {globalErrorStyles}\n \n )\n }\n }\n\n return {\n GlobalError: GlobalErrorComponent,\n styles: globalErrorStyles,\n }\n}\n\nfunction createSelectStaleTime(experimental: ExperimentalConfig) {\n return (stale: number) =>\n stale === INFINITE_CACHE &&\n typeof experimental.staleTimes?.static === 'number'\n ? experimental.staleTimes.static\n : stale\n}\n\nasync function collectSegmentData(\n fullPageDataBuffer: Buffer,\n prerenderStore: PrerenderStore,\n ComponentMod: AppPageModule,\n renderOpts: RenderOpts\n): Promise