Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Remove prospective fallback prerenders #79304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 0 additions & 52 deletions 52 packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ import {
} from '../server/lib/experimental/ppr'
import { FallbackMode, fallbackModeToFallbackField } from '../lib/fallback'
import { RenderingMode } from './rendering-mode'
import { getParamKeys } from '../server/request/fallback-params'
import { InvariantError } from '../shared/lib/invariant-error'
import { HTML_LIMITED_BOT_UA_RE_STRING } from '../shared/lib/router/utils/is-bot'
import type { UseCacheTrackerKey } from './webpack/plugins/telemetry-plugin/use-cache-tracker-utils'
Expand Down Expand Up @@ -1613,10 +1612,6 @@ export default async function build(
const serverPropsPages = new Set<string>()
const additionalPaths = new Map<string, PrerenderedRoute[]>()
const staticPaths = new Map<string, PrerenderedRoute[]>()
const prospectiveRenders = new Map<
string,
{ page: string; originalAppPath: string }
>()
const appNormalizedPaths = new Map<string, string>()
const fallbackModes = new Map<string, FallbackMode>()
const appDefaultConfigs = new Map<string, AppSegmentConfig>()
Expand Down Expand Up @@ -1975,31 +1970,6 @@ export default async function build(

staticPaths.set(originalAppPath, [])
}
// As PPR isn't enabled for this route, if dynamic IO
// is enabled, and this is a dynamic route, we should
// complete a prospective render for the route so that
// we can use the fallback behavior. This lets us
// check that dynamic pages won't error when they
// enable PPR.
else if (config.experimental.dynamicIO && isDynamic) {
// If there's a page with a more specific render
// available, then we should skip the prospective
// render because it'll be done as a part of the
// that render to validate the dynamic state.
if (
// The existence of any prerendered routes when
// PPR is disabled means that the route has more
// specific prerendered routes that should be
// used for the diagnostic render anyways.
!workerResult.prerenderedRoutes ||
workerResult.prerenderedRoutes.length === 0
) {
prospectiveRenders.set(originalAppPath, {
page,
originalAppPath,
})
}
}

if (workerResult.prerenderedRoutes) {
staticPaths.set(
Expand Down Expand Up @@ -2718,28 +2688,6 @@ export default async function build(
})
})

// If the app does have dynamic IO enabled but does not have PPR
// enabled, then we need to perform a prospective render for all
// the dynamic pages to ensure that they won't error during
// rendering (due to a missing prelude).
for (const {
page,
originalAppPath,
} of prospectiveRenders.values()) {
defaultMap[page] = {
page: originalAppPath,
_ssgPath: page,
_fallbackRouteParams: getParamKeys(page),
// Prospective renders are only enabled for app pages.
_isAppDir: true,
// Prospective renders are only enabled when PPR is disabled.
_isRoutePPREnabled: false,
_isProspectiveRender: true,
// Dynamic IO does not currently support `dynamic === 'error'`.
_isDynamicError: false,
}
}

if (i18n) {
for (const page of [
...staticPages,
Expand Down
52 changes: 0 additions & 52 deletions 52 packages/next/src/export/routes/app-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,58 +30,6 @@ import type { RequestLifecycleOpts } from '../../server/base-server'
import type { AppSharedContext } from '../../server/app-render/app-render'
import type { MultiFileWriter } from '../../lib/multi-file-writer'

export async function prospectiveRenderAppPage(
req: MockedRequest,
res: MockedResponse,
page: string,
pathname: string,
query: NextParsedUrlQuery,
fallbackRouteParams: FallbackRouteParams | null,
partialRenderOpts: Omit<RenderOpts, keyof RequestLifecycleOpts>,
sharedContext: AppSharedContext
): Promise<undefined> {
const afterRunner = new AfterRunner()

// If the page is `/_not-found`, then we should update the page to be `/404`.
// UNDERSCORE_NOT_FOUND_ROUTE value used here, however we don't want to import it here as it causes constants to be inlined which we don't want here.
if (page === '/_not-found/page') {
pathname = '/404'
}

try {
await lazyRenderAppPage(
new NodeNextRequest(req),
new NodeNextResponse(res),
pathname,
query,
fallbackRouteParams,
{
...partialRenderOpts,
waitUntil: afterRunner.context.waitUntil,
onClose: afterRunner.context.onClose,
onAfterTaskError: afterRunner.context.onTaskError,
},
undefined,
false,
sharedContext
)

// TODO(after): if we abort a prerender because of an error in an after-callback
// we should probably communicate that better (and not log the error twice)
await afterRunner.executeAfter()
} catch (err) {
if (!isDynamicUsageError(err)) {
throw err
}

// We should fail rendering if a client side rendering bailout
// occurred at the page level.
if (isBailoutToCSRError(err)) {
throw err
}
}
}

/**
* Renders & exports a page associated with the /app directory
*/
Expand Down
21 changes: 1 addition & 20 deletions 21 packages/next/src/export/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { createRequestResponseMocks } from '../server/lib/mock-request'
import { isAppRouteRoute } from '../lib/is-app-route-route'
import { hasNextSupport } from '../server/ci-info'
import { exportAppRoute } from './routes/app-route'
import { exportAppPage, prospectiveRenderAppPage } from './routes/app-page'
import { exportAppPage } from './routes/app-page'
import { exportPagesPage } from './routes/pages'
import { getParams } from './helpers/get-params'
import { createIncrementalCache } from './helpers/create-incremental-cache'
Expand Down Expand Up @@ -104,10 +104,6 @@ async function exportPageImpl(
// the renderOpts.
_isRoutePPREnabled: isRoutePPREnabled,

// If this is a prospective render, we don't actually want to persist the
// result, we just want to use it to error the build if there's a problem.
_isProspectiveRender: isProspectiveRender = false,

// Configure the rendering of the page not to throw if an empty static shell
// is generated while rendering using PPR.
_doNotThrowOnEmptyStaticShell: doNotThrowOnEmptyStaticShell = false,
Expand Down Expand Up @@ -287,21 +283,6 @@ async function exportPageImpl(
buildId: input.buildId,
}

// If this is a prospective render, don't return any metrics or revalidate
// timings as we aren't persisting this render (it was only to error).
if (isProspectiveRender) {
return prospectiveRenderAppPage(
req,
res,
page,
pathname,
query,
fallbackRouteParams,
renderOpts,
sharedContext
)
}

return exportAppPage(
req,
res,
Expand Down
1 change: 0 additions & 1 deletion 1 packages/next/src/server/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const zExportMap: zod.ZodType<ExportPathMap> = z.record(
_isAppDir: z.boolean().optional(),
_isDynamicError: z.boolean().optional(),
_isRoutePPREnabled: z.boolean().optional(),
_isProspectiveRender: z.boolean().optional(),
_doNotThrowOnEmptyStaticShell: z.boolean().optional(),
})
)
Expand Down
10 changes: 0 additions & 10 deletions 10 packages/next/src/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -743,16 +743,6 @@ export type ExportPathMap = {
*/
_isRoutePPREnabled?: boolean

/**
* When true, it indicates that this page is being rendered in an attempt to
* discover if the page will be safe to generate with PPR. This is only
* enabled when the app has `experimental.dynamicIO` enabled but does not
* have `experimental.ppr` enabled.
*
* @internal
*/
_isProspectiveRender?: boolean

/**
* When true, it indicates that the diagnostic render for this page is
* disabled. This is only used when the app has `experimental.ppr` and
Expand Down
2 changes: 1 addition & 1 deletion 2 packages/next/src/server/request/fallback-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getRouteRegex } from '../../shared/lib/router/utils/route-regex'

export type FallbackRouteParams = ReadonlyMap<string, string>

export function getParamKeys(page: string) {
function getParamKeys(page: string) {
const pattern = getRouteRegex(page)
const matcher = getRouteMatcher(pattern)

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.