Files
Aurora ScharffandGitHub 18d2e2da5f Insights: use a single Learn more link in console errors (#95967)
## Summary

The instant / blocking-prerender insight console errors printed a docs
URL under each fix option (two or three anchors per message). This
collapses them to a single `Learn more:` link at the end of each
message, while keeping the `[stream]`/`[cache]`/`[block]` fix-option
labels. It restores the single-link format these builders originally
shipped with.

**Before:**

```
Ways to fix this:
  - [stream] Provide a placeholder with `<Suspense fallback={...}>` around the data access
    https://nextjs.org/docs/messages/blocking-prerender-runtime#wrap-in-or-move-into-suspense
  - [block] Set `export const instant = false` to allow a blocking route
    https://nextjs.org/docs/messages/blocking-prerender-runtime#allow-blocking-route
```

**After:**

```
Ways to fix this:
  - [stream] Provide a placeholder with `<Suspense fallback={...}>` around the data access
  - [block] Set `export const instant = false` to allow a blocking route

Learn more: https://nextjs.org/docs/messages/blocking-prerender-runtime
```

Covers all 16 insight-kind errors, across `blocking-route-messages.ts`,
`sync-io-messages.ts`, `dynamic-rendering-utils.ts`, and
`instant-messages.ts`.

Because the dev overlay classified these errors by the `#`-anchored docs
URL, `getBlockingRouteErrorDetails` is updated to match the anchor-less
`Learn more:` URL. Console-message snapshots and the guidance-data
extraction test are updated to the new format. The dev-overlay fix-card
data (`instant-guidance-data.ts`) keeps its per-card links, since those
are the overlay UI rather than the console message.

## Verification

- `pnpm --filter=next types`
- Snapshots regenerated with `jest -u` for the affected suites

<!-- NEXT_JS_LLM -->
2026-07-21 12:53:17 +02:00

543 lines
28 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { nextTestSetup } from 'e2e-utils'
import path from 'path'
const { version: nextVersion } = require('next/package.json')
const cacheComponentsEnabled = process.env.__NEXT_CACHE_COMPONENTS === 'true'
describe('build-output-prerender', () => {
describe('with a next config file', () => {
describe('without --debug-prerender', () => {
const { next, isTurbopack, isRspack } = nextTestSetup({
files: path.join(__dirname, 'fixtures/with-config-file'),
skipStart: true,
})
beforeAll(() => next.build())
it('prints only the user-selected experimental flags (and the ones enabled via env variable)', async () => {
if (cacheComponentsEnabled) {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Turbopack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
✓ serverComponentsHmrCancellation (enabled by \`__NEXT_EXPERIMENTAL_SERVER_COMPONENTS_HMR_CANCELLATION\`)
· staticGenerationMaxConcurrency: 1"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Rspack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
· staticGenerationMaxConcurrency: 1"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (webpack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
· staticGenerationMaxConcurrency: 1"
`)
}
} else {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Turbopack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
· staticGenerationMaxConcurrency: 1
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Rspack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
· staticGenerationMaxConcurrency: 1"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (webpack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
· staticGenerationMaxConcurrency: 1
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)"
`)
}
}
})
it('shows only a single prerender error with a mangled stack', async () => {
if (isTurbopack) {
// TODO(veil): Why is the location incomplete unless we enable --no-mangling?
expect(getPrerenderOutput(next.cliOutput)).toMatchInlineSnapshot(`
"Error: Route "/client": Next.js encountered the unstable value \`new Date()\` in a Client Component.
This value would be evaluated during the prerender, instead of recomputed on each visit.
Ways to fix this:
- [stream] Wrap the Client Component in \`<Suspense fallback={...}>\`
- [defer] Move the read into a \`useEffect\` or event handler
- [measure] If the value is for telemetry, use a timing API such as \`performance.now()\`
Learn more: https://nextjs.org/docs/messages/blocking-prerender-current-time-client
at <unknown> (app/client/page.tsx:4:28)
2 |
3 | export default function Page() {
> 4 | return <p>Current time: {new Date().toISOString()}</p>
| ^
5 | }
6 |
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/client" in your browser to investigate the error.
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
Error occurred prerendering page "/client". Read more: https://nextjs.org/docs/messages/prerender-error
Export encountered an error on /client/page: /client, exiting the build."
`)
} else {
expect(getPrerenderOutput(next.cliOutput)).toMatchInlineSnapshot(`
"Error: Route "/client": Next.js encountered the unstable value \`new Date()\` in a Client Component.
This value would be evaluated during the prerender, instead of recomputed on each visit.
Ways to fix this:
- [stream] Wrap the Client Component in \`<Suspense fallback={...}>\`
- [defer] Move the read into a \`useEffect\` or event handler
- [measure] If the value is for telemetry, use a timing API such as \`performance.now()\`
Learn more: https://nextjs.org/docs/messages/blocking-prerender-current-time-client
at x (<next-dist-dir>)
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/client" in your browser to investigate the error.
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
Error occurred prerendering page "/client". Read more: https://nextjs.org/docs/messages/prerender-error
Export encountered an error on /client/page: /client, exiting the build."
`)
}
})
})
describe('with --debug-prerender', () => {
const { next, isTurbopack, isRspack } = nextTestSetup({
files: path.join(__dirname, 'fixtures/with-config-file'),
skipStart: true,
buildArgs: ['--debug-prerender'],
})
beforeAll(() => next.build())
it('prints a warning and the customized experimental flags', async () => {
if (cacheComponentsEnabled) {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Turbopack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
✓ serverComponentsHmrCancellation (enabled by \`__NEXT_EXPERIMENTAL_SERVER_COMPONENTS_HMR_CANCELLATION\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
· staticGenerationMaxConcurrency: 1
⨯ turbopackMinify (disabled by \`--debug-prerender\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Rspack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
· staticGenerationMaxConcurrency: 1"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (webpack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
· staticGenerationMaxConcurrency: 1"
`)
}
} else {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Turbopack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
· staticGenerationMaxConcurrency: 1
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)
⨯ turbopackMinify (disabled by \`--debug-prerender\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Rspack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
· staticGenerationMaxConcurrency: 1"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (webpack)
✓ Running next.config.js took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
· staticGenerationMaxConcurrency: 1
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)"
`)
}
}
})
it('shows all prerender errors with readable stacks and code frames', async () => {
if (isTurbopack) {
expect(getPrerenderOutput(next.cliOutput)).toMatchInlineSnapshot(`
"Error: Route "/client": Next.js encountered the unstable value \`new Date()\` in a Client Component.
This value would be evaluated during the prerender, instead of recomputed on each visit.
Ways to fix this:
- [stream] Wrap the Client Component in \`<Suspense fallback={...}>\`
- [defer] Move the read into a \`useEffect\` or event handler
- [measure] If the value is for telemetry, use a timing API such as \`performance.now()\`
Learn more: https://nextjs.org/docs/messages/blocking-prerender-current-time-client
at Page (app/client/page.tsx:4:28)
2 |
3 | export default function Page() {
> 4 | return <p>Current time: {new Date().toISOString()}</p>
| ^
5 | }
6 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/client" in your browser to investigate the error.
Error occurred prerendering page "/client". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Route "/server": Next.js encountered the unstable value \`Math.random()\` while prerendering.
This value can change between renders, so it must be either prerendered or computed later.
Ways to fix this:
- [dynamic] Render at request time by adding a dynamic data access (e.g. \`await connection()\`) before this call
- [cache] Prerender and cache the value with \`"use cache"\`
- [client] Render the value on the client with \`"use client"\`
Learn more: https://nextjs.org/docs/messages/blocking-prerender-random
at Page (app/server/page.tsx:13:27)
at Page (<anonymous>)
11 | await cachedDelay()
12 |
> 13 | return <p>Random: {Math.random()}</p>
| ^
14 | }
15 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/server" in your browser to investigate the error.
Error occurred prerendering page "/server". Read more: https://nextjs.org/docs/messages/prerender-error
> Export encountered errors on 2 paths:
/client/page: /client
/server/page: /server"
`)
} else {
// TODO(veil): Bundler protocols should not appear in stackframes.
expect(getPrerenderOutput(next.cliOutput)).toMatchInlineSnapshot(`
"Error: Route "/client": Next.js encountered the unstable value \`new Date()\` in a Client Component.
This value would be evaluated during the prerender, instead of recomputed on each visit.
Ways to fix this:
- [stream] Wrap the Client Component in \`<Suspense fallback={...}>\`
- [defer] Move the read into a \`useEffect\` or event handler
- [measure] If the value is for telemetry, use a timing API such as \`performance.now()\`
Learn more: https://nextjs.org/docs/messages/blocking-prerender-current-time-client
at Page (webpack:///app/client/page.tsx:4:28)
at ClientPageRoot (webpack:///src/client/components/client-page.tsx:56:10)
2 |
3 | export default function Page() {
> 4 | return <p>Current time: {new Date().toISOString()}</p>
| ^
5 | }
6 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/client" in your browser to investigate the error.
Error occurred prerendering page "/client". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Route "/server": Next.js encountered the unstable value \`Math.random()\` while prerendering.
This value can change between renders, so it must be either prerendered or computed later.
Ways to fix this:
- [dynamic] Render at request time by adding a dynamic data access (e.g. \`await connection()\`) before this call
- [cache] Prerender and cache the value with \`"use cache"\`
- [client] Render the value on the client with \`"use client"\`
Learn more: https://nextjs.org/docs/messages/blocking-prerender-random
at Page (webpack:///app/server/page.tsx:13:27)
at Page (<anonymous>)
11 | await cachedDelay()
12 |
> 13 | return <p>Random: {Math.random()}</p>
| ^
14 | }
15 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/server" in your browser to investigate the error.
Error occurred prerendering page "/server". Read more: https://nextjs.org/docs/messages/prerender-error
> Export encountered errors on 2 paths:
/client/page: /client
/server/page: /server"
`)
}
})
})
})
describe('without a next config file', () => {
describe('without --debug-prerender', () => {
const { next, isTurbopack, isRspack } = nextTestSetup({
files: path.join(__dirname, 'fixtures/without-config-file'),
skipStart: true,
})
beforeAll(() => next.build())
it('prints no experimental flags (unless enabled via env variable)', async () => {
if (cacheComponentsEnabled) {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Turbopack)
✓ Running next.config took N
- Cache Components enabled
- Experiments (use with caution):
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
✓ serverComponentsHmrCancellation (enabled by \`__NEXT_EXPERIMENTAL_SERVER_COMPONENTS_HMR_CANCELLATION\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Rspack)
✓ Running next.config took N
- Cache Components enabled
- Experiments (use with caution):
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (webpack)
✓ Running next.config took N
- Cache Components enabled
- Experiments (use with caution):
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)"
`)
}
} else {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Turbopack)
✓ Running next.config took N
- Experiments (use with caution):
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (Rspack)
✓ Running next.config took N
- Experiments (use with caution):
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"▲ Next.js x.y.z (webpack)
✓ Running next.config took N
- Experiments (use with caution):
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)"
`)
}
}
})
})
describe('with --debug-prerender', () => {
const { next, isTurbopack, isRspack } = nextTestSetup({
files: path.join(__dirname, 'fixtures/without-config-file'),
skipStart: true,
buildArgs: ['--debug-prerender'],
})
beforeAll(() => next.build())
it('prints a warning and the customized experimental flags', async () => {
if (cacheComponentsEnabled) {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Turbopack)
✓ Running next.config took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
✓ serverComponentsHmrCancellation (enabled by \`__NEXT_EXPERIMENTAL_SERVER_COMPONENTS_HMR_CANCELLATION\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
⨯ turbopackMinify (disabled by \`--debug-prerender\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Rspack)
✓ Running next.config took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (webpack)
✓ Running next.config took N
- Cache Components enabled
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
✓ cachedNavigations (enabled by \`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)"
`)
}
} else {
if (isTurbopack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Turbopack)
✓ Running next.config took N
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)
⨯ turbopackMinify (disabled by \`--debug-prerender\`)"
`)
} else if (isRspack) {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (Rspack)
✓ Running next.config took N
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)"
`)
} else {
expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(`
"⚠ Prerendering is running in debug mode with NODE_ENV='development'. This will affect performance and should not be used for production.
▲ Next.js x.y.z (webpack)
✓ Running next.config took N
- Experiments (use with caution):
✓ allowDevelopmentBuild (enabled by \`--debug-prerender\`)
⨯ appNewScrollHandler (disabled by \`__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER\`)
⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`)
⨯ serverMinification (disabled by \`--debug-prerender\`)
✓ serverSourceMaps (enabled by \`--debug-prerender\`)
✓ strictRouteTypes (enabled by \`__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES\`)"
`)
}
}
})
})
})
})
function getPreambleOutput(cliOutput: string): string {
const lines: string[] = []
for (const line of cliOutput.split('\n')) {
if (line.includes('Creating an optimized production build')) {
break
}
lines.push(
line
.replace(nextVersion, 'x.y.z')
// The config evaluation timing varies between runs, so normalize it to
// keep the snapshot stable (e.g. "took 21ms" -> "took N").
.replace(/(Running .* took )[\d.]+(ms|s|min)/, '$1N')
)
}
return lines.join('\n').trim()
}
function getPrerenderOutput(cliOutput: string): string {
let foundPrerenderingLine = false
const lines: string[] = []
for (const line of cliOutput.split('\n')) {
if (line.includes('Collecting page data')) {
foundPrerenderingLine = true
continue
}
if (line.includes('Next.js build worker exited')) {
break
}
if (foundPrerenderingLine && !line.includes('Generating static pages')) {
lines.push(
line.replace(/at \w+ \(.next[^)]+\)/, 'at x (<next-dist-dir>)')
)
}
}
return lines.join('\n').trim()
}