685 Commits

Author SHA1 Message Date
Sebastian "Sebbie" Silbermann 7b222b9095 [backport][test] Pin package manager to patch versions (#93595) 2026-05-07 15:32:13 +02:00
Sebastian "Sebbie" Silbermann 672b02b270 [next-playwright] Use unique cookie values for instant navigation testing lock (#91250)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-03-16 21:07:56 +00:00
Luke Sandberg 2e4f08ca0a fix(build): don't block SSG on telemetry flush, add persistence spans to trace-build (#91335)
### What?

Two fixes for the Turbopack build tracing introduced in #90397:

1. **Don't block SSG on Turbopack shutdown**: `workerMain()` no longer awaits the shutdown promise before returning. Trace event collection is deferred to `waitForShutdown()`, which the parent process awaits *after* SSG completes. This allows static generation and Turbopack persistence/cache-flush to run in parallel.

2. **Add persistence spans to `trace-build` allowlist**: `turbopack-build-events`, `turbopack-persistence`, and `turbopack-compaction` are now included in the `to-json-build.ts` allowlist so they appear in `.next/trace-build`.

### Why?

- The `await shutdownPromise` in `workerMain()` was too eager — it prevented the caller from acknowledging the build as complete and starting SSG until Turbopack persistence finished flushing to disk.
- The persistence/compaction spans emitted by Rust (`turbopack-persistence`, `turbopack-compaction`) were not in the `to-json-build.ts` allowlist, so they were silently filtered out of `.next/trace-build`.

### How?

**`impl.ts` (worker)**:
- Removed `await shutdownPromise` from `workerMain()` — it now returns build results immediately
- `waitForShutdown()` now returns `{ debugTraceEvents }` after awaiting shutdown, so trace events are collected only after all compilation events (including persistence spans) have been processed

**`index.ts` (parent)**:
- Moved `recordTraceEvents(debugTraceEvents)` from the `workerMain` result handler into the `shutdownPromise` `.then()` chain, so events are replayed into the parent reporter after shutdown completes

**`to-json-build.ts`**:
- Added `turbopack-build-events`, `turbopack-persistence`, `turbopack-compaction` to the allowlist

**Test updates**:
- Enabled `turbopackFileSystemCacheForBuild: true` in the trace-build test fixture
- Updated the Turbopack inline snapshot to include `turbopack-build-events`
2026-03-15 23:42:17 -07:00
Will Binns-Smith 5394d39a62 [Turbopack] write route bundle stats to .next/diagnostics/route-bundle-stats.json (#90949)
After a successful, Turbopack production build, this writes
`.next/diagnostics/route-bundle-stats.json`
containing First Load JS stats for every route. 

## Why?

We used to have route bundle size statistics print after every build. It
was not very high-signal and could be misleading, often using heuristics
to give a best-effort estimate of what sizes may be at runtime. **These
kinds of metrics for route bundle sizes can be misleading, as pages can
be slow to visual/interactive completeness even if they have small first
load bytes.**

However, a minimal gauge of how much JavaScript a route ships during
initial page load can be a useful signal so long as users have
additional context and awareness of their app structure. Let's provide
just this number for now for those that could benefit.

Additionally, this does so in the form of writing a json document to the
build directory, rather than writing a table to stdout, where users have
needed to write extra tools to parse.

## Format

An array of route entries sorted descending by
`firstLoadUncompressedJsBytes`:

```json
[
  {
    "route": "/blog/[slug]",
    "firstLoadUncompressedJsBytes": 124928,
    "firstLoadChunkPaths": [
      ".next/static/chunks/framework.js",
      ".next/static/chunks/main.js",
      ".next/static/chunks/pages/blog/[slug].js"
    ]
  }
]
```

`firstLoadUncompressedJsBytes`: sum of uncompressed sizes of all JS
chunks loaded on first navigation to the route (shared chunks included),
for both Pages Router and App Router
`firstLoadChunkPaths`: paths to those chunks relative to the project
root

## Test Plan
Added an integration test. Built with a create-next-app and verified the
json document is written and the numbers align with what Chrome reports
during initial load of a page.
2026-03-13 14:48:51 -07:00
Sebastian "Sebbie" Silbermann 156307e3a3 [test] Show decoded binary WebSocket messages in traces (#91308) 2026-03-13 21:11:18 +01:00
Sebastian "Sebbie" Silbermann 0b1604a8c4 [test] Properly log framereceived payload (#91266) 2026-03-12 19:23:14 +01:00
Janka Uryga 7bbea9d4b1 [Instant] Build-time validation (#90964)
Initial version of build-time instant validation.

During prerendering, if we have `unstable_instant` configs, we perform a
complete staged render of the page (including dynamic data). This render
mocks request data (`params`/`searchParams`/`cookies`/`headers`) using
the `samples` provided in `unstable_instant`. Then, we use the staged
chunks to run instant validation in mostly the same way that we would in
dev. Most changes in the validation flow are related to samples, which
also need to be passed into the client render to mock APIs like
`useParams`.

### Providing Mock data

We run everything in a fresh workStore+workUnitStore to (hopefully)
avoid any data from the prerender from sneaking in. This is quite
involved.

A big part of the trickiness is that if you do e.g. `(await
cookies()).get('myCookie')` but the `samples` don't contain `myCookie`,
we want the validation to error and require explicitly saying what state
`myCookie` is in.
If it's available, use
```ts
export const unstable_instant = {
  // ...
  samples: { cookies: [{ name: "myCookie", value: "someValue" }] }
}
```
If it's not available, use
```ts
export const unstable_instant = {
  // ...
  samples: { cookies: [{ name: "myCookie", value: null }] }
}
```
This explicitness makes it harder to e.g. unintentionally validate a
logged-out state.

Note that even validating a `prefetch: 'static'` page might require
samples, because we need the shared parent for the navigation to be
(mostly) complete. We might be able to relax this in the future, but
it's not straightforward.

Another issue is that a segment might access a missing sample in a
"benign" way, i.e. where it wouldn't block validation (or be inside a
suspense boundary). Ideally we wouldn't require providing a sample for
usages like that, but currently we do.

### Instrumenting APIs to detect missing samples

All request APIs are instrumented in this way.
- `params` throw when accessing a property that was not declared in
`samples`. same for the object from `useParams()`. `in` is allowed
because we know the shape of the params object statically, based on the
routing structure.
- `searchParams` throw when accessing a property that was not declared
in `samples` and `in` checks.
- objects returned from `cookies()`, `headers()`, `useSearchPrams()`
throw on `get()` and `has()`.

There's a lot of tests for this behavior in `instant-validation-build`.

One gap is that iteration/enumeration is currently not instrumented.
We're punting on it for now and will revisit in a follow-up.

### Relation to prerender

We kick off the validation after the prerender, in
`renderToHTMLOrFlightImpl`. Ideally, we should kick this off somewhere
higher up, separately from the prerender itself, but we're leaving that
for future work.

Note that if we do multiple prerenders for the same page (e.g. due to
`generateStaticParams`, we'll only run validation for the first
prerender for that route. `generateStaticParams` is not currently
integrated into the validation at all, i.e. we don't use those params to
validate, so this is safe. All params need to be provided via `samples`.
This will likely change in the future, but we're not sure how yet.

### Disabling build validation

Build-time instant validation is experimental, and has more potential
problems to deal with than dev validation. To allow incremental rollout
and testing, we allow disabling it per instant config:
```ts
export const unstable_instant = {
  unstable_disableBuildValidation: true
  // ...
}
```

for parity, there's also `unstable_disableBuildValidation`, but we don't
expect that to see much use.
2026-03-12 14:57:38 +01:00
Sebastian "Sebbie" Silbermann ca5e33d7ad [ci] Disable test-level retries during flakiness detection (#91261)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-03-12 12:37:43 +00:00
Hendrik Liebau d08f4dc08c Add experimental.cachedNavigations feature flag (#90928)
The recent Cached Navigations feature introduced navigation-level
caching into the segment cache, where static and dynamic RSC data from
navigations and initial HTML loads is cached so that repeat visits can
be served instantly. This feature is currently gated behind
`cacheComponents`, meaning it activates for all projects that enable
Cache Components.

This change introduces a new `experimental.cachedNavigations` flag that
independently controls the Cached Navigations behavior. The flag
defaults to `false` so we can investigate potential regressions that the
feature might have introduced without affecting the broader Cache
Components functionality.

The flag requires `cacheComponents` to also be enabled and throws a
configuration error if `cachedNavigations` is set without it. On the
server, the staged rendering paths in `app-render.tsx` (both RSC request
handling and initial HTML rendering) now check `cacheComponents &&
cachedNavigations` before producing staged responses. On the client,
`process.env.__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS` is used alongside
`process.env.__NEXT_CACHE_COMPONENTS` for compile-time dead code
elimination in the stream tee (`app-index.tsx`) and the response
processing (`fetch-server-response.ts`).

The cached navigations test suite enables the flag via `next.config.ts`,
and the Cache Components CI jobs export
`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS=true` to maintain test coverage.
2026-03-06 10:39:47 +01:00
JJ Kasper da6fb315d5 Cleanup non-generic assertions in our deploy test suite (#90894)
This makes sure we don't have assertions that will only pass in one
environment e.g. these should work for running against bun and not just
node or against a local metadata URL not just a deployed https fully
qualified domain. Ensures others can leverage this test suite for their
own verification easily.
2026-03-04 15:59:07 -08:00
JJ Kasper f18e688589 Add custom cleanup script support for deploy tests (#90696)
## Summary
- Adds `cleanupScriptPath` workflow dispatch input and
`NEXT_TEST_CLEANUP_SCRIPT_PATH` env var to `test_e2e_deploy_release.yml`
(webpack + turbopack jobs)
- Adds `cleanupUsingCustomScript()` method to `NextDeployInstance`
following the same pattern as the existing deploy and logs scripts
- Calls the cleanup script in `destroy()` before existing teardown logic

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-02-28 09:41:50 -08:00
Niklas Mischkulnig 96512309ce tests: Fix immutableAssetToken extraction (#90668)
Fixes this deploy test failure:
https://github.com/vercel/next.js/actions/runs/22499483165/attempts/2

The output might be:
```
Building: └ ○ /nested
Building: ○  (Static)   prerendered as static content
Building: ƒ  (Dynamic)  server-rendered on demand
Building: > @ post-build /vercel/path0
Building: > node -e 'console.log("BUILD" + "_ID: " + fs.readFileSync(".next/BUILD_ID") + "\nDEPLOYMENT" + "_ID: " + process.env.NEXT_DEPLOYMENT_ID + "\nIMMUTABLE_ASSET" + "_TOKEN: " + process.env.VERCEL_IMMUTABLE_ASSET_TOKEN)'
Building: BUILD_ID: build-TfctsWXpff2fKS
Building: DEPLOYMENT_ID: dpl_5Qad8NbhCPWn7QRf5TiCePi58vVi
Building: IMMUTABLE_ASSET_TOKEN: undefined
Building: Build Completed in /vercel/output [15s]
Building: Deploying outputs...
Building: Deployment completed
```

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-02-28 00:47:33 +00:00
Niklas Mischkulnig 4d5840e3b7 Turbopack: experimental.immutableAssetToken (#88607)
This allows specifying a different deployment id for static immutable assets

- [x] rename `getImmutableAssetToken` to `getAssetToken` (because it can be non-immutable as well)
- [x] disable for webpack

Closes PACK-6534

For https://github.com/nextjs/adapter-vercel/pull/25

Part of PACK-6802
2026-02-27 11:55:47 +01:00
Niklas Mischkulnig 1c1550ca7b tests: Assert dpl query string in all tests for Turbopack (#90592)
Enable skew protection for all start-mode tests when Turbopack is enabled (i.e. not dev). This works by setting `NEXT_DEPLOYMENT_ID` in the test infra

- When running the tests, `packages/next/src/server/lib/router-utils/resolve-routes.ts` now validates that all static asset requests have the correct `?dpl=...` query param value, and returns a 404 if missing.
- It can be disabled with `disableAutoSkewProtection: true` in the test options
- There were various tests that were asserting URLs and were missing the optional `?dpl` at the end.
   - `next.getDeploymentIdQuery()` can be used to get the `?dpl=dpl_123912js` string (or an empty string)
   - `next.getAssetQuery()` currently behaves like `getDeploymentIdQuery`, but will switch to prefer the immutable static token in #88607
2026-02-27 10:06:14 +01:00
Hendrik Liebau 420560d0fe [ci] Use NEXT_TEST_CI instead of CI for e2e test retry guard (#90606)
`run-tests.js` explicitly unsets `CI` in the spawned Jest child process
and preserves the original value as `NEXT_TEST_CI`. Since
`test/lib/e2e-utils/index.ts` runs inside that child process,
`process.env.CI` is always empty, making the `jest.retryTimes(1)` call
effectively dead code in CI.
2026-02-26 17:38:02 +00:00
Sebastian "Sebbie" Silbermann a8de0a0044 Enable experimental.reactDebugChannel by default (#90310)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-02-26 16:00:47 +01:00
Sebastian "Sebbie" Silbermann 7d98e0b534 [test] Include error code in Redbox snapshot (#90497) 2026-02-26 11:01:25 +00:00
Sebastian "Sebbie" Silbermann 5c24c44440 [test] Remove getStackFramesContent (#90571) 2026-02-26 10:39:51 +01:00
Andrew Clark 299e1ff318 Remove revalidation settling period from router-act (#90531)
The 500ms settling period in router-act's `act()` polled for 500ms after
the request queue emptied before exiting. This was added to accommodate
the 300ms revalidation cooldown in the client router — after a server
action calls `revalidatePath`/`revalidateTag`, the client delays
re-prefetching for 300ms. The settling period ensured `act()` waited
long enough to catch the resulting re-prefetch.

The settling period applied to every `act()` call, not just ones
involving revalidation, adding ~500ms per call across 28 test files.
Remove it entirely and instead use Playwright's fake clock
(`page.clock.install` / `page.clock.fastForward`) in the revalidation
tests to deterministically control the cooldown. This is both faster and
architecturally cleaner — the test utility no longer embeds knowledge of
a specific client-side timer.
2026-02-25 18:36:04 -05:00
Niklas Mischkulnig 02af7ed3a4 test: Improve test assertions to prepare for dpl query string (#90463)
*This doesn't enable skew protection for any new tests, only preparation*

Prepare a lot of test assertions so that they work correctly when a `?dpl=123` query param is present:
- some regexes should accept the query
- some places assumed that the `<script>`'s `src` is a valid pathname, whereas it might have a query param that has to be stripped before removing the path
- some hardcoded build ids instead of `next.buildId`
2026-02-25 12:16:10 +01:00
Hendrik Liebau b8cbaad24c [test] Only auto-retry individual e2e tests in CI (#90464)
The per-test `jest.retryTimes(1)` added in #89929 is useful for CI
resilience & performance but produces confusing logs and adds
unnecessary wait time when investigating test failures locally.

We're now only enabling the retry when running in CI so that local runs
fail fast on the first attempt.
2026-02-24 22:31:34 +00:00
Sebastian "Sebbie" Silbermann aa6d7c2271 [devtools] Omit empty looking error messages (#90256)
If the trimmed error message has no length, we skip the line entirely to remove useless vertical space from the Redbox. Errors with no messages are assumed to only be relevant due to their stack.
2026-02-20 15:21:21 -08:00
Hendrik Liebau 074ba4a953 [test] Improve fetch timeout error stack for act (#90261)
Before:

```
    apiRequestContext.fetch: Request timed out after 30000ms
    Call log:
      - → GET http://localhost:55200/refetch-on-new-base-tree/a?_rsc=1u5ob
      -   <snip>

      225 |             // server; we pass the request to the server the immediately.
      226 |             result: (async () => {
    > 227 |               const originalResponse = await page.request.fetch(request, {
          |                                                           ^
      228 |                 maxRedirects: 0,
      229 |               })
      230 |

      at fetch (lib/router-act.ts:227:59)
      at lib/router-act.ts:245:13
      at routeHandler (lib/router-act.ts:257:7)
```

After:

```
    apiRequestContext.fetch: Request timed out after 30000ms
    Call log:
      - → GET http://localhost:61662/refetch-on-new-base-tree/a?_rsc=1u5ob
      -   <snip>

      264 |
      265 |     // Reveal the links to trigger prefetches
    > 266 |     await act(async () => {
          |           ^
      267 |       await linkALinkVisibilityToggle.click()
      268 |       await linkBLinkVisibilityToggle.click()
      269 |     }, [

      at Object.act (e2e/app-dir/segment-cache/revalidation/segment-cache-revalidation.test.ts:266:11)
```

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2026-02-20 13:02:16 -08:00
Niklas Mischkulnig a6d950a445 Turbopack: fix static asset skew protection for edge and prerenders (#90238)
- Edge Runtime was missing `globalThis.NEXT_CLIENT_ASSET_SUFFIX` at runtime
- Prerenders were always running `globalThis.NEXT_CLIENT_ASSET_SUFFIX` set

Fixups after #88828
2026-02-20 18:31:02 +01:00
Janka Uryga 415e0df7a1 [Instant] speed up test instant-validation suite (#90214)
This PR speeds up the `instant-validation` test suite from 450s down to
~100s. We were wasting a lot of time in `waitForNoErrorToast()`, which
ends up waiting almost 15s by default.

The trick is to add some debug logs inside app-render to track when
instant validation started/ended. If we know that the validation is
finished, we can just wait for a short time, because if there were
errors, a toast would be displayed very quickly.

Note that is a stopgap -- when we add a "Validating..." indicator, we
won't have to emit the log and can just wait for the indicator instead.
But in the meantime, waiting for the tests is pretty painful, so this is
worth doing.
2026-02-20 06:57:04 +01:00
Niklas Mischkulnig 445d880ef9 test: Don't run integration tests twice for Turbopack (#83335)
This should reduce some duplicate CI jobs.
This split existed to support separate dev/prod manifests for skipping tests. That's not needed anymore, so we can just switch to the Webpack setup. This manual partitioning of `integration` tests into dev vs prod was brittle anyway
We still need this setup for rspack though
2026-02-18 18:57:16 +01:00
Sebastian "Sebbie" Silbermann 5509e1bf7a [fragment-scroll] Stop focusing the first focusable host descendant (#89903)
Flagged behind `experimental.appNewScrollHandler`

`focus()` on Fragment refs works different than `findDOMNode(this).focus()`.

`findDOMNode` will return an actual host element so it's effectively `HTMLElement.focus()`. If the element isn't focuseable, `focus()` will do nothing. By spec, there's also no way to determine if an element is focusable. It's up to user agents (e.g. sometimes scrollable containers are considered focusable). 

`FragmentInstance.focus` will focus the first focusable descendant. That could be a focusable element deep within the fragment e.g. `<Fragment><section><p>A lot of text</p><a href="">Next page</a></Fragment>`. Focusing such a deep element may sometimes be counter productive.

Now we just blur the active element. This is how a hard navigation already works today and ensures we don't skip past content of the new segment.

This means you potentially stay a long way before the actual Segment (e.g. in a preceding nav) with the focus cursor which could be annoying. We could be clever and temporarily insert a focusable element at the start of the Segment, focus it, and then immediately remove. That would leave the focus cursor right before the Segment. However, this requires knowledge about the parent content (can we just insert an element of our choosing?) and relies on knowing what's focusable (a button would be a good bet). That's a bit too clever for a fix without concrete motivation so I'm waiting somebody to complain about the new behavior.
2026-02-18 09:50:39 -08:00
Sebastian "Sebbie" Silbermann d1d2912ec3 [devtools] Add support for error causes in the dev overlay (#90108) 2026-02-17 23:33:11 +00:00
Luke Sandberg a7c61c10ad [turbopack] Run the deployment tests for turbopack and webpack (#84360)
Fork the set of deployment tests so they run with both turbopack and
webpack. Now that turbopack is the default bundler we need this
coverage.

Because we are now running twice as many tests, decrease concurrency,
otherwise we hit rate limits on vercel. There were attempts to improve
rate limit recovery in the vercel CLI
(https://github.com/vercel/vercel/pull/14443 and
https://github.com/vercel/vercel/pull/14407) which helped but did not
solve the issue. Also there was an investigation into the API service
where we discovered some suspicious but ultimately correct code
(https://github.com/vercel/api/pull/55967).

The basic issue is that the vercel CLI polls `api-deployments-get`
fairly aggressively at the beginning of a deploymnet, and since we start
so many deployments in parallel we will always hit the rate limits. The
recovery logic in the CLI is good but has (reasonably) a fixed set of
retries it will attempt, inevitably some tasks get unlucky. So retrying
the test does work, but really we should slow down which is what we do
here. 😥


https://github.com/vercel/next.js/actions/runs/20290161194/job/58272593085

Fixes PACK-5613

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-02-17 11:52:10 -08:00
Janka Uryga 85d74bb4e2 [Instant] allow non-blocking dynamic holes and errors in shared parents (#89875)
Closes NAR-777
2026-02-17 20:45:59 +01:00
JJ Kasper ce738b9f8c Disable jest cache for CI instead of wiping (#90097)
This is aiming to fix sporadic failures from jest transforms which is
most likely caused by the change to output to custom jest-cache folder
and wipe that between runs. Instead this disables the cache via
`--no-cache` flag and also fixes WASM bindings issue that started due to
cache not being available.

x-ref:
https://github.com/vercel/next.js/actions/runs/22109996356/job/63903450669?pr=90096#step:35:493
x-ref:
https://github.com/vercel/next.js/actions/runs/22109996356/job/63903820197?pr=90096#step:35:18167
2026-02-17 10:34:54 -08:00
JJ Kasper 960437cfcc Always set adapter deploy env variable (#90064)
This ensures we always set this env variable so that it overrides any
flag opt ins when we specifically want to test with or without the
adapter.
2026-02-16 15:56:48 -08:00
JJ Kasper f8e47d49b0 test: scope e2e timeouts to startup and per-it (#89929)
This aims to avoid us having tests stall for upwards of 240s when a
single assertion in the test stalls. This is very common currently. To
also avoid wasting the entire time of resetting the test suite this also
allows 1 retry for individual failed assertions. This won't always work
since some assertions rely on previous setup so this also keeps the
entire test suite retry handling as a fallback.

This change is not applied for dev tests as they check HMR and compile
lazily.

## Summary
- keep elevated Jest timeout for test setup/startup in e2e-utils
- enforce a 60s default timeout for individual `it`/`test` cases
- apply one retry per individual test via `jest.retryTimes(1)`

## Verification
- pnpm testonly test/development/gssp-notfound/index.test.ts
- pnpm testonly test/development/enoent-during-require/index.test.ts
- pnpm testonly test/e2e/custom-app-render/custom-app-render.test.ts

Tested against our deploy tests to see if this helps:

Current run
[21967823508](https://github.com/vercel/next.js/actions/runs/21967823508)

Jobs: 24 (with test-runner output: 20)
Whole-suite retry starts: 11 (retry 1: 8, retry 2+: 3)
Jobs that needed suite retries: 8
Unique test files retried: 7

Previous run
[21964085768](https://github.com/vercel/next.js/actions/runs/21964085768)

Jobs: 26 (with test-runner output: 20)
Whole-suite retry starts: 18 (retry 1: 13, retry 2+: 5)
Jobs that needed suite retries: 9
Unique test files retried: 12
2026-02-16 15:41:19 -08:00
Sebastian "Sebbie" Silbermann 9662feb629 [fragment-scroll] Ensure hoisted elements don't break scroll-to-top on page navigations (#83108) 2026-02-14 14:42:31 +01:00
Sebastian "Sebbie" Silbermann 3dafc76fc1 [fragment-scroll] Add experimental.appNewScrollHandler (#83107)
Just plumbing and enabling that flag in the experimental shards. The flag will enable our Layout router to use Fragment refs for scroll restoration. Implementation will be done in a follow-up.
2026-02-12 14:54:38 +01:00
Sebastian "Sebbie" Silbermann c49cc9faf8 [test] Ensure new deploy test builds have the necessary env variables (#89846) 2026-02-11 21:23:27 +01:00
Sebastian "Sebbie" Silbermann ba01f6578c [test] Enable scroll related tests in Cache Component tests (#83245) 2026-02-11 16:20:08 +01:00
JJ Kasper 0d15dd58bb Add separate E2E deploy env for turbopack tests (#89458)
x-ref: [slack
thread](https://vercel.slack.com/archives/C04KC8A53T7/p1770151130656569?thread_ts=1770107873.440639&cid=C04KC8A53T7)
2026-02-03 21:13:12 +00:00
JJ Kasper b19e6d4498 Add custom deploy and logs env for next-deploy (#89206)
## Summary

Adds support for custom deploy scripts in the `next-deploy` test mode
via two new environment variables:

- `NEXT_TEST_DEPLOY_SCRIPT_PATH` - Path to a custom script that deploys
the project and outputs the deployment URL to stdout
- `NEXT_TEST_DEPLOY_LOGS_SCRIPT_PATH` - Path to a custom script that
fetches build logs (required when using custom deploy script)

This allows running deploy tests against non-Vercel deployment targets.

### Priority Order

1. `NEXT_TEST_DEPLOY_URL` - If set, uses existing deployment (no deploy
happens)
2. `NEXT_TEST_DEPLOY_SCRIPT_PATH` - If set, uses custom deploy script  
3. Default Vercel CLI logic - If neither is set

### Script Interface

**Deploy script** receives:
- `NEXT_TEST_DIR` - The test directory containing the Next.js project
- All test-specific environment variables
- Must output deployment URL to stdout

**Logs script** receives:
- `NEXT_TEST_DIR` - The test directory
- `NEXT_TEST_DEPLOY_URL` - The deployment URL
- Must output build logs containing `BUILD_ID: <id>` pattern

Verified existing flow is still working in:
https://github.com/vercel/next.js/actions/runs/21465304133
2026-01-28 20:13:52 -08:00
JJ Kasper e196d515f7 Remove Vercel specific assertions from E2E deploy (#89198)
This aims to remove assertions that were specific to Vercel so that
other platforms can re-use our E2E deploy workflow.
2026-01-28 19:08:49 -08:00
JJ Kasper 1104c45f25 Add full adapters E2E tests to workflow (#89125)
This updates to run the entire E2E deploy tests same as we do currently
but with adapters enabled to catch regressions there. These run on a
separate test team to isolate from existing test team and avoid rate
limits.

Test run of the workflow done here
https://github.com/vercel/next.js/actions/runs/21418745794
2026-01-28 14:16:20 -08:00
Sebastian "Sebbie" Silbermann a04499797e Re-enable types-and-precompiled (#89070) 2026-01-26 23:19:43 +00:00
JJ Kasper 93bb2799fe Apply fixes for onBuildComplete and route module (#88831)
This applies fixes for outputs in `onBuildComplete` with various slight
differences from expected values. This also applies some fixes in the
route-module interface to ensure we install the process handlers for PPR
since currently that was done in `next-server` which we want to get rid
of and there was an edge case with query parsing logic in the
route-module.

Our E2E tests were run against this here to validate
https://github.com/vercel/next.js/actions/runs/21324578779 and failures
are matching existing failures on canary.

x-ref: https://github.com/nextjs/adapter-vercel/pull/11
x-ref: https://github.com/vercel/vercel/pull/14574

---------

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
2026-01-25 18:59:20 -08:00
Wyatt Johnson 092458fd6a feat: implement LRU cache with invocation ID scoping for minimal mode response cache (#88509)
## Summary

Implements an LRU cache with compound keys for the minimal mode response
cache to improve cache hit rates during parallel revalidation scenarios.

**Problem**: The previous single-entry cache (`previousCacheItem`) keyed
by pathname caused cache collisions when multiple concurrent invocations
(e.g., during ISR revalidation) accessed the same pathname. Each
invocation would overwrite the previous entry, leading to cache misses
and redundant work.

**Solution**: An LRU cache using compound keys (`pathname +
invocationID`) that allows multiple invocations to cache entries for the
same pathname independently:

```
Cache Key Structure
─────────────────────
/blog/post-1\0inv-abc  →  {entry, expiresAt}
/blog/post-1\0inv-def  →  {entry, expiresAt}
/blog/post-1\0__ttl__  →  {entry, expiresAt}  (TTL fallback)
/api/data\0inv-ghi     →  {entry, expiresAt}
```

### Cache Key Strategy

- **With `x-invocation-id` header**: Entries are keyed by invocation ID
for exact-match lookups (always a cache hit if the entry exists)
- **Without header (TTL fallback)**: Entries use a `__ttl__` sentinel
key and validate via expiration timestamp

### Configuration via Environment Variables

Cache sizing can be tuned via environment variables (using
`NEXT_PRIVATE_*` prefix for infrastructure-level settings):

| Environment Variable | Default | Description |
|---------------------|---------|-------------|
| `NEXT_PRIVATE_RESPONSE_CACHE_MAX_SIZE` | 150 | Max entries in the LRU
cache |
| `NEXT_PRIVATE_RESPONSE_CACHE_TTL` | 10000 | TTL in ms for cache
entries (fallback validation) |

### LRU Cache Enhancement

Added an optional `onEvict` callback to `LRUCache` that fires when
entries are evicted due to capacity limits. This enables tracking
evicted invocation IDs for warning detection without introducing
timer-based cleanup.

### Eviction Warnings

When a cache entry is evicted and later accessed by the same invocation,
a warning is logged suggesting to increase
`NEXT_PRIVATE_RESPONSE_CACHE_MAX_SIZE`. This helps developers tune cache
sizes for their workload.

### Additional Changes

- Renamed header from `x-vercel-id` to `x-invocation-id` for clarity
- Added `withInvocationId()` test helper for cache testing

## Test Plan

- Existing response cache tests pass with updated header name
- Unit tests for `LRUCache` including `onEvict` callback behavior
- Updated standalone mode tests to use `withInvocationId()` helper
2026-01-22 11:45:15 -07:00
Sebastian "Sebbie" Silbermann 71ac1ec75c [devtools] Wrap long file names of stack frames in the error overlay (#88886)
https://github.com/user-attachments/assets/0594744b-5dd5-4550-90b8-77071962f666

See [overflow-wrap docs](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/overflow-wrap) for break-word vs anywhere.


Just a one-line CSS change. The other changes are renaming functions to disambiguate source/codeframe and the filename.
2026-01-22 12:38:35 +01:00
Zack Tanner 6138452203 [test]: add ability to run test-deploy with pre-existing deployment (#88829)
When digging into failing deployment tests, I often will re-run the test
itself without wanting to change anything about Next.js or the test
application, especially when I suspect a logic bug in the test itself or
need to figure out what's causing a flake.

This adds an environment variable that can be used to skip the
build/deploy step and will use an existing deployment URL to run the
tests against.

I suggest reviewing this [without
whitespace](https://github.com/vercel/next.js/pull/88829/changes?w=1).
2026-01-20 14:40:49 -08:00
Niklas Mischkulnig eb14325ed4 Turbopack: remove deployment id suffix from client reference manifest chunks (#88741)
Closes PACK-6539

When `experimental.runtimeServerDeploymentId` is enabled, read the `process.env.NEXT_DEPLOYMENT_ID` and append to the chunks when evaluating the `client-reference-manifest.js`

Originally, I tried to do it after the manifest is loaded (in `loadComponents` or in the `RouteModule.prepare`) to "hydrate" the manifest, but that is too late because the manifest needs to be initialized immediately to make module-evaluation-time server actions work (which need the manifest immediately)
2026-01-20 16:11:24 +01:00
Hendrik Liebau 48fdf48ebc Apply buildArgs also for deploy tests (via package.json) (#88731)
This change ensures that the `buildArgs` specified in `nextTestSetup` are also applied when running deploy tests. This is achieved by modifying the build command in the `package.json` file used for deploy tests to include the specified `buildArgs`.

See also https://vercel.com/docs/builds/configure-a-build#build-command.

The only current e2e test that uses the `buildArgs` option is `test/e2e/react-compiler/react-compiler.test.ts`, but that one is excluded from deploy tests via `deploy-tests-manifest.json`.
2026-01-19 21:25:15 +01:00
Hendrik Liebau 7a2f4ad140 Type-check run-tests.js and remove unused related flag (#88433)
The file already had the `@ts-check` directive, so the IDE did show errors in that file. But since it was not included in the root `tsconfig.json`, those errors were not reported during CI runs.

One issue found this way was that the `related` flag was defined but never used. The referenced script was removed in #67644.
2026-01-12 19:46:11 +01:00
Tim Neutkens 16c7ed28a2 Tests: Reduce loglines from apply patch delay (#88224)
Apply #83800 without merge conflicts.
2026-01-09 16:35:21 +01:00