Skip to content

Commit

Permalink
[dynamicIO] routes with dynamic segments should be able to be static …
Browse files Browse the repository at this point in the history
…in dev

Dev mode reports static/dynamic behavior using a heuristic when dynamicIO is enabled. The heuristic previously incorrectly marked routes as dynamic when they were in fact static as a consequence of refactoring metadata to support streaming. This update adjust the heuristic to not incorrectly assume dynamic in these situations.

The root cause is that errors in `onError` cannot be assumed to be valid if the render has already aborted
  • Loading branch information
gnoff committed Feb 28, 2025
1 parent 93a43ee commit 70a9324
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 16 deletions.
6 changes: 1 addition & 5 deletions packages/next/src/export/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,7 @@ async function exportAppImpl(
strictNextHead: nextConfig.experimental.strictNextHead ?? true,
deploymentId: nextConfig.deploymentId,
htmlLimitedBots: nextConfig.htmlLimitedBots.source,
streamingMetadata:
// Disable streaming metadata when dynamic IO is enabled.
// FIXME: remove dynamic IO guard once we fixed the dynamic indicator case.
// test/e2e/app-dir/dynamic-io/dynamic-io.test.ts - should not have static indicator on not-found route
!nextConfig.experimental.dynamicIO,
streamingMetadata: true,
experimental: {
clientTraceMetadata: nextConfig.experimental.clientTraceMetadata,
expireTime: nextConfig.expireTime,
Expand Down
6 changes: 1 addition & 5 deletions packages/next/src/export/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,7 @@ export async function exportPages(
enableExperimentalReact: needsExperimentalReact(nextConfig),
sriEnabled: Boolean(nextConfig.experimental.sri?.algorithm),
buildId: input.buildId,
streamingMetadata:
// Disable streaming metadata when dynamic IO is enabled.
// FIXME: remove dynamic IO guard once we fixed the dynamic indicator case.
// test/e2e/app-dir/dynamic-io/dynamic-io.test.ts - should not have static indicator on not-found route
!nextConfig.experimental.dynamicIO,
streamingMetadata: true,
}),
// If exporting the page takes longer than the timeout, reject the promise.
new Promise((_, reject) => {
Expand Down
9 changes: 8 additions & 1 deletion packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2446,6 +2446,7 @@ async function spawnDynamicValidationInDev(
}
)

let rootDidError = false
const serverPhasedStream = serverPrerenderStreamResult.asPhasedStream()
try {
const prerender = require('react-dom/static.edge')
Expand Down Expand Up @@ -2476,7 +2477,12 @@ async function spawnDynamicValidationInDev(
isPrerenderInterruptedError(err) ||
finalClientController.signal.aborted
) {
requestStore.usedDynamic = true
if (!rootDidError) {
// If the root errored before we observe this error then it wasn't caused by something dynamic.
// If the root did not error or is erroring because of a sync dynamic API or a prerender interrupt error
// then we are a dynamic route.
requestStore.usedDynamic = true
}

const componentStack = errorInfo.componentStack
if (typeof componentStack === 'string') {
Expand All @@ -2501,6 +2507,7 @@ async function spawnDynamicValidationInDev(
}
)
} catch (err) {
rootDidError = true
if (
isPrerenderInterruptedError(err) ||
finalClientController.signal.aborted
Expand Down
6 changes: 1 addition & 5 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,11 +600,7 @@ export default abstract class Server<
isExperimentalCompile: this.nextConfig.experimental.isExperimentalCompile,
// `htmlLimitedBots` is passed to server as serialized config in string format
htmlLimitedBots: this.nextConfig.htmlLimitedBots,
streamingMetadata:
// Disable streaming metadata when dynamic IO is enabled.
// FIXME: remove dynamic IO guard once we fixed the dynamic indicator case.
// test/e2e/app-dir/dynamic-io/dynamic-io.test.ts - should not have static indicator on not-found route
!this.nextConfig.experimental.dynamicIO,
streamingMetadata: true,
experimental: {
expireTime: this.nextConfig.expireTime,
clientTraceMetadata: this.nextConfig.experimental.clientTraceMetadata,
Expand Down

0 comments on commit 70a9324

Please sign in to comment.