Commit Graph

1310 Commits

Author SHA1 Message Date
Jiachi Liu 3f239eea13 [devtool] highlight all link in error message (#86084) 2025-11-13 20:27:27 +01:00
Jiachi Liu 1f0322f23c perf: revert to use the light safe stringify for is-error (#86053)
`is-error` is a helper that being used accorss client and server now, in
#84909 we switched the underlying safe stringify error implementation to
the precompiled dependency `safe-stable-stringify`. But it increased the
client bundle size a bit.

The change in #84909 was only for applying the `safe-stable-stringify`
for client file logger with mcp, not really necessary need to change for
is-error helper

Note: Save minified around 12kb. it's actually 7.5kb on bundlephobia,
but because we're using ncc to compile it to cjs dependency that the
size seems slightly larger than their metrics. The saved gzip size would
be around 2-3.x kb
2025-11-13 02:14:46 +01:00
Hendrik Liebau b6a7714057 Hoist inner 'use cache' functions to reduce function allocations (#85904)
This PR fixes a slight performance regression introduced in #85519 where
inline async function expressions were created for each unique set of
arguments passed to a `'use cache'` function.

For a function like this:

```js
export async function getCachedData(id) {
  'use cache';
  return fetch(`/api/data/${id}`);
}
```

we were previously generating (simplified):

```js
export var $$RSC_SERVER_CACHE_0 = cache("default", "0815", 0, async function(id) {
  return fetch(`/api/data/${id}`);
});
```

In #85519, we restructured this to ensure proper stack frames in error
messages (simplified):

```js
export var $$RSC_SERVER_CACHE_0 = React.cache(function getCachedData() {
  return cache("default", "0815", 0, async function(id) {
    return fetch(`/api/data/${id}`);
  }, arguments);
});
```

However, this introduced a small performance issue: the inner async
function expression was passed inline to the cache wrapper. While
`React.cache` memoizes the outer function, each unique set of arguments
would cause a new inner function object to be allocated.

Now we're generating (simplified):

```js
const $$RSC_SERVER_CACHE_0_INNER = async function getCachedData(id) {
  return fetch(`/api/data/${id}`);
};

export var $$RSC_SERVER_CACHE_0 = React.cache(function getCachedData() {
  return cache("default", "0815", 0, $$RSC_SERVER_CACHE_0_INNER, arguments);
});
```

The cache implementation is now hoisted to module scope with an `_INNER`
suffix as a const declaration with a named function expression. The
function name is preserved to ensure proper stack traces in dev. This
eliminates the repeated function allocations while preserving the
improvements from #85519.
2025-11-10 13:09:59 +01:00
Jiachi Liu 7fbd9de880 [mcp] get_routes mcp tool (#85773) 2025-11-06 15:53:35 +01:00
Cong-Cong Pan ed41ac1a74 chore: upgrade rspack 1.6.0 (#84210)
1. Fixed the incremental update bug in buildChunkGraph.
2. Fixed a bug in Rspack's built-in CssChunkingPlugin.

For detailed release information, please see
https://github.com/web-infra-dev/rspack/releases.

Note: All the faulty Rspack test cases on GitHub, from what I can see,
either time out or also produce errors in Rspack version 1.5.0.

---------

Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
2025-11-06 01:29:04 +00:00
Sebastian "Sebbie" Silbermann 0b58a32c45 [test] assert* -> waitFor* when the util is not instant (#85450) 2025-10-30 14:44:08 +01:00
Sebastian "Sebbie" Silbermann cfe8c602f9 [test] Regenerate tsconfig.json files (#85515) 2025-10-30 10:09:23 +01:00
Sebastian "Sebbie" Silbermann e3b3b1a9ab [test] Avoid needless start/stop from using createSandbox (#85507)
`createSandbox` fully isolates the returned session from the existing
Next instance by restarting the server.

This is wasteful if the existing instance is already started. Some tests
called `nextTestSetup()` without `skipStart` which got fixed in this PR.

Some tests can just use `patchFile` nowadays instead of `createSandbox`.
2025-10-29 13:55:45 +01:00
Sebastian "Sebbie" Silbermann efbc187d62 [test] Speed up refresh test (#85505) 2025-10-29 11:42:44 +00:00
Sebastian "Sebbie" Silbermann b0837e0f24 [test] Exclude likely Next.js internal Components from component stacks in Redbox assertions (#85420) 2025-10-28 11:30:28 +00:00
Sebastian "Sebbie" Silbermann 9a87d2079a [test] Unflake typed-env suite (#85410) 2025-10-27 21:11:39 +01:00
Zack Tanner 47ceda3c14 [cache components] persist cache bypass UI until it's disabled (#85190)
Previously we were only showing this during navigations when caches are
bypassed. We want to make it clearer that you are in this state and dev
might not work as intended while caches are disabled.

This will show the cache bypass status on initial load and will reset
the next time a router action occurs that doesn't bypass cache.


https://github.com/user-attachments/assets/f82a98c6-b5be-44d0-ba86-e4f7ca7010e4
2025-10-21 16:04:48 -07:00
Andrew Clark 96754b605f Tweaks to blocking route error message (#85191)
Makes it more clear that `<Suspense>` and "use cache" are separate
approaches for fixing the error, not requirements.

<img width="969" height="711" alt="Screenshot 2025-10-21 at 3 09 57 PM"
src="https://github.com/user-attachments/assets/34bd2efc-9fee-4aba-82eb-6b395663d765"
/>
2025-10-21 18:24:29 -04:00
Andrew Clark 077da10374 Fix Activity boundary names (#85185)
Follow-up to #85155. Made a mistake in the context-passing logic.
2025-10-21 17:40:00 -04:00
Andrew Clark 782d04db1f Update blocking prerender error message (#85087) 2025-10-21 15:50:35 +00:00
Sebastian "Sebbie" Silbermann 0364b65984 [test] Update snapshots (#85171) 2025-10-21 15:22:30 +02:00
Andrew Clark 5b5830526a Update Activity names given to routes (#85155)
In practical terms, clicking the name of a route segment in the Suspense
DevTools should select the child slots of that layout, because when you
focus on it, what you're interested in debugging are navigations that
occur within the shared layout.

So the name we apply to the Activity boundary is actually based on the
name of the *parent* segment.
2025-10-21 05:58:38 -04:00
Andrew Clark 683a318d79 Omit params to from client segments (#84883)
If a layout or page is marked with "use client", we do not need to pass
any runtime params from the server; the client can parse them from the
URL, or (in the case of a rewrite) from the x-next-rewritten-path and
x-next-rewritten-query headers. This means the client can treat the
segment as fully static, and no dynamic request is necessary upon
navigation.
2025-10-21 03:33:54 -04:00
Benjamin Woodruff 40f48ebb5e Turbopack: Remove redundant log line, increase delay for compiling log message (#85133)
We've already got output logging for this stuff, and the "compiling" message is too noisy.

Only print `Compiling /...` it if the compilation takes more than 3s, stop printing `Compiled in` altogether.

After this PR:
<img width="1075" height="335" alt="Screenshot 2025-10-20 at 3 15 59 PM" src="https://github.com/user-attachments/assets/34e87d18-8feb-4470-ae11-0d8e4b3a8a6b" />

Removes this line:
<img width="1095" height="254" alt="Screenshot 2025-10-20 at 3 17 56 PM" src="https://github.com/user-attachments/assets/76fb795e-760a-4782-889a-dd98bcf09125" />
2025-10-20 22:53:45 -07:00
Zack Tanner fbbd538036 [BF Cache]: skip lazyData fetch logic for inactive segments (#85142)
When `routerBfCache` is enabled, React's Activity API renders inactive
route segments offscreen to enable instant back/forward navigation.
However, the layout-router's lazy data fetching logic was incorrectly
triggering fetchServerResponse calls for these offscreen segments when
data was missing.

This PR adds an isActive prop to InnerLayoutRouter that tracks whether a
segment is currently visible via the existing `stateKey` check.
2025-10-20 19:28:08 -07:00
Janka Uryga 42b02b0771 [Cache Components] fix env labels in perf track test (#85132)
We updated the label for the Runtime stage to `Prefetchable` in #85076,
and #85111 wasn't rebased on top of that
2025-10-21 00:13:12 +02:00
Jiachi Liu 98adcb3f86 telemetry: mcp tool call (#85120) 2025-10-20 14:42:25 -07:00
Benjamin Woodruff 167608775c fix(experimental.lockDistDir): Acquire the lock in dev earlier (#85116)
Apparently I grabbed the lock too late, which led to the second process still managing the `distDir` before exiting... https://vercel.slack.com/archives/C03EWR7LGEN/p1760910025067089

This moves the acquisition earlier for dev, and extends the e2e test to cover this.

[Screen Recording 2025-10-20 at 10.42.49 AM.webm <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/user-attachments/thumbnails/68785bda-1dd5-437a-bf16-54de2d54a49c.webm" />](https://app.graphite.dev/user-attachments/video/68785bda-1dd5-437a-bf16-54de2d54a49c.webm)
2025-10-20 14:25:51 -07:00
Sebastian "Sebbie" Silbermann 2346cfd67d [test] Current behavior of dynamic APIs integration with React DevTools (#85111) 2025-10-20 23:04:53 +02:00
Tobias Koppers 3567c153b3 Turbopack: improve module evaluation name (#84633)
### What?

We can use the demangled name directly, which is much easier and applies to more cases.
2025-10-20 14:03:50 -07:00
Zack Tanner 20cf4c07da add new devtools indicator loading state (#85083)
This removes the Next logo animation/dimming and replaces it with more
explicit states. We also use this UI to show when caches are being
warmed (when using Cache Components). When caches are being bypassed in
DevTools, we also will show this in the indicator with warning text,
indicating that we cannot accurately reflect what can be statically
prerendered.



https://github.com/user-attachments/assets/665d4f8b-8c01-4def-a60e-bc4ecdd1f879
2025-10-20 12:42:43 -07:00
Janka Uryga 2ed06f03e8 label as Prefetch/Prefetchable depending on prefetch config (#85076)
Tweaks the environment label logic to only use label things as
`Prefetch` if there's a runtime prefetch config. If there's none, we
label it as `Prefetchable` instead.

---------

Co-authored-by: Josh Story <story@hey.com>
2025-10-20 10:34:35 -07:00
Zack Tanner 7147642e4e [devtools]: instrument client navigation hooks for suspense devtools (#85007)
Various navigation hooks (eg `usePathname`, `useParams`) could suspend
during SSR/prerendering even though they don't necessarily suspend
during client side navigation (because it was likely part of a prefetch
response). React's Suspense DevTools show all the possible things that
could have suspended on the page, but without us calling `use` in these
hooks, there'd be no way for React to track them as IO in the same way
that we do during prerendering.

In development, this instruments all of the client navigation hooks to
call `use` on a fulfilled promise set to the same value that we would
have returned previously. For hooks like `useSelectedLayoutSegment`, I'm
storing a map of promises at each level of layout (because these hooks
take a parallel route key argument and values are relative to the
calling layout's position in the tree). These are eagerly pre-computed
during dev.
2025-10-19 23:29:02 -07:00
Zack Tanner 09772c3aa8 [cache components] add cache components indicator to dev start (#85069)
Missed the plumbing for this in `dev`.
2025-10-19 12:54:00 -07:00
Jiachi Liu 79e127afbd enable mcp server by default (#85058) 2025-10-19 11:43:33 -07:00
Sebastian "Sebbie" Silbermann f8f24aa479 Plumbing for cache indicator (#84955) 2025-10-19 17:25:50 +00:00
Zack Tanner 7336e834f9 [cache components]: show cache components enabled in DevTools (#85048)
Similar to how in DevTools we show if Turbopack is enabled, this shows
that Cache Components is enabled. In the future, we might have a similar
CTA to suggest enabling the feature. For now it only shows if it's
actually enabled.
2025-10-18 22:00:25 -07:00
Zack Tanner 85c3d20a91 [cache components]: move flag out of experimental (#85035)
This moves `experimental.cacheComponents` to a top level config. As part
of this, I disabled some tests in `build-output-prerender` that assert
on `cacheComponents` appearing in the experimental list. In a separate
PR, I'm going to show that Cache Components is enabled next to the
bundler info.

This also updates some docs pages to remove "experimental" language.
2025-10-18 14:13:44 -07:00
Janka Uryga 66376415ab [Cache Components] separate runtime stage in dev render (#84644)
This PR extends dev rendering with an extra stage - Runtime, where we
resolve Runtime APIs (`cookies()`, `params`, etc), but not dynamic APIs
(e.g. `connection()`, uncached fetches). This separation requires some
changes to `makeDevtoolsIOPromise` and other tasky delay code that we've
had in place before.|

I've implemented this as `StagedRenderingController` (generally accessed
via `requestStore.stagedRendering`), which allows creating promises that
resolve in the correct stage.
```ts
stagedRendering.delayUntilStage(RenderStage.Runtime, cookiesObject) // resolves in the runtime stage
stagedRendering.delayUntilStage(RenderStage.Dynamic, somethingDynamic)  // resolves in the dynamic stage
```

Notably, in the case where the initial render has cache misses and we
only use it as a cache warmup, we can also use this to _not_ resolve
dynamic promises, which saves us from doing some unncecessary (uncached)
work. This means that, if the render ends up being a warmup, dynamic
promises can be left hanging (and later aborted), similar to how
`makeHangingPromise` works in a prerender.

For simplicity and compatibility with other codepaths, most callsites
that need a staged promise still use `makeDevtoolsIOAwarePromise`, but
now they pass in a stage argument to control the timing if we are
rendering with stages.

---

Based on the stage, we now add a third environment label -- "Prefetch",
to correspond with runtime prefetches. This label is currently applied
even if there's no prefetch config in place, which is a bit confusing,
and will be addressed in a follow-up (if there's no runtime prefetch
config, we want to label runtime logs as "Server" even if they run in a
separate stage).
2025-10-16 17:08:02 +02:00
Josh Story 76d2beaeb8 [Cache Components] Remove unstable prefix from unstable_cacheTag (#84880)
`cacheLife` is now stable and does not require an unstable prefix
2025-10-16 07:01:44 -07:00
Janka Uryga b7b153f623 [Cache Components] Fix cacheSignal in dev render (#84846)
This PR changes the timing used in `CacheSignal.cacheReady()` to work
correctly when rendering, not just prerendering. When rendering, React
schedules new work in `setImmediate` (as opposed to using a microtask
when prerendering), and `CacheSignal.cacheReady()` needs to account for
that, because we need to wait longer to make sure that react had time to
render and thus we've started all the relevant cache reads.

Note that this PR increases the delay for both prerender _and_ render.
This is to make it easier to reason about (by not having separate
codepaths), but also to not be so tightly coupled to React pinging work
in a microtask when prerendering, in case that changes in the future.
2025-10-15 18:32:43 +02:00
Jiachi Liu c34ea8f280 fix: always use the safe stable stringify (#84909) 2025-10-15 09:02:07 -07:00
Josh Story 8cab15c0c9 [Cache Components] Remove unstable prefix from unstable_cacheLife (#84877)
`cacheLife` is now stable and does not require an unstable prefix
2025-10-15 08:14:04 -07:00
Jiwon Choi d540fbd3e6 Deprecate Middleware API and add Proxy API (#84764)
Following up on https://github.com/vercel/next.js/pull/84119, this PR
deprecated the user-facing middleware API and added a replacement Proxy
API.

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2025-10-14 20:09:14 +02:00
Janka Uryga f06d951d6a [Cache Components] Dev - restart render on cache miss (#84088)
This PR replaces the previous approach to the dev-time cache warmup. On
full-page requests, we
1. We attempt an initial RSC render. It uses a RequestStore, but
includes a `cacheSignal` and a `prerenderResumeDataCache` to be filled
1. if there's no cache misses, we use the RSC render as is, and move
onto SSR
2. If there's any cache misses in the static stage (i.e. during the
first timeout), we treat the inital render as a prospective render, use
it only for filling caches, and discard the result
3. Once caches are filled, we render RSC again (using a fresh
RequestStore, with a filled `renderResumeDataCache`), and use this
second stream for SSR instead.

With this strategy, we minimize the amount of work we need to do for
cache warming -- once caches for a page are filled, we can render it in
one go, with no separate cache-filling render necessary.

---

A lot of the effort here goes into trying to reflect the behavior of a
static prerender into what we do during a dynamic render -- if something
would be a dynamic hole (hanging promise) in a prerender, we shouldn't
resolve it microtaskily (in the static stage). Instead, we have to delay
it into a future timeout (the dynamic stage). In this PR, we're still
using `makeDevtoolsIOAwarePromise` for this (i.e. just `new
Promise((resolve) => setTimeout(resolve))`), though this will change to
a more precise mechanism in #84644.
The timing of when promises resolve is currently tested in
`cache-components.dev-warmup.test.ts`, where we check the environment
labels on the server logs replayed in the browser, and use that to
verify which "phase" (Static/Dynamic) a given API resolves in.

This will be the foundation for prefetch validation, where we'll need to
snapshot what was rendered in each stage (Static/Runtime/Dynamic) and
use that to validate whether a prefetch would result in an instant
navigation.

Note that there's currently a bug involving `params` and `searchParams`
-- they can currently incorrectly resolve in the static phase (because
those promises are created before we start the actual render). We're not
(yet) relying on the timing of these promises for anything critical, so
it's fine to leave it for now. This bug will be addressed in #84644,
where I introduce a more precise mechanism for controlling the timing of
promise resolution, which also lets us separate "runtime" APIs like
`cookies` into a separate phase.

---

I've also left the current `spawnDynamicValidationInDev` codepath as is,
so after the we're done with all the render restarting, we'll still kick
off a validation prerender. This will also change in the future (and
could be optimized -- we've already ensured that all the caches are
filled, so we could e.g. skip the prospective render there) but I'm
trying not to do everything at once.

---------

Co-authored-by: Josh Story <story@hey.com>
2025-10-14 16:33:05 +02:00
Jiachi Liu e300821614 [mcp] capture next config schema errors (#84832) 2025-10-13 15:08:03 -07:00
Sebastian "Sebbie" Silbermann 53e104259d Revert "Fix flakey overlay feedback test" (#84819) 2025-10-13 17:19:48 +02:00
Jiwon Choi cf76c5b72d Update test/CNA templates React version to 19.2.0 (#84736)
The peerDeps are already bumped to 19.2.0 at
https://github.com/vercel/next.js/pull/84463, but the test/CNA templates
weren't updated as the `syncPagesRouterReact` value is always false at
the moment, which blocked the update.

Therefore, remove the `syncPagesRouterReact` condition to match the
actual peerDeps bump.

---------

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-10-13 10:10:10 +00:00
Sebastian "Sebbie" Silbermann 6feaddf73e Remove unused eslint-disable directives (#84797)
Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
2025-10-12 23:17:08 +02:00
Benjamin Woodruff 61a8037835 Rspack: Fix lockfile test on rspack (#84707)
Noticed this on https://github.com/vercel/next.js/pull/84673

We don't run rspack test on every PR, so this wasn't caught before.
2025-10-09 17:28:04 -07:00
Wyatt Johnson 3630146458 Add validation for missing default.js in parallel routes (#84702)
### What?

Adds build-time validation to require explicit `default.js` files for
all parallel route slots (except the implicit "children" slot). This
validation is implemented in both Webpack and Turbopack bundlers.

### Why?

Parallel routes without `default.js` files currently cause silent 404
errors when users navigate to those routes. This creates confusion and
hard-to-debug issues because the routes appear to be configured
correctly but fail at runtime without any indication of what went wrong.

By making this validation explicit at build time, developers get
immediate feedback about missing required files with clear error
messages and documentation links, catching configuration mistakes before
deployment.

### How?

**Rust/Turbopack** (`crates/next-core/src/app_structure.rs`): Added
`MissingDefaultParallelRouteIssue` that emits a build error when a
parallel route slot is missing its `default.js` file. The validation is
skipped for the "children" slot since it's implicit and doesn't require
a default file.

**Webpack**
(`packages/next/src/build/webpack/loaders/next-app-loader/index.ts`):
Added validation that throws `MissingDefaultParallelRouteError` when
`default.js` cannot be resolved. The "children" slot falls back to the
existing `PARALLEL_ROUTE_DEFAULT_PATH` behavior for backward
compatibility.

**Error Class**
(`packages/next/src/shared/lib/errors/missing-default-parallel-route-error.ts`):
New error type with helpful messaging that includes the slot path,
explanation of the requirement, and a link to documentation.

**Migration Path**: Users who want the previous 404 behavior can
explicitly create a `default.js` that calls `notFound()`, or return
`null` for empty slots:

```tsx
import { notFound } from 'next/navigation'

export default function Default() {
  notFound()
}
```

Users can also run the following Deno script to generate the default
files for them:
https://gist.github.com/wyattjoh/ba7263ecb637ef399d3e3e4db63ffbd6

**Breaking Change**: This is a breaking change timed for Next.js 16
beta. Builds will now fail if parallel route slots are missing required
`default.js` files.
2025-10-09 15:20:52 -06:00
JJ Kasper e598a4f976 Add new updateTag API and new signature for revalidateTag (#83822) 2025-10-09 14:03:01 -07:00
Sebastian "Sebbie" Silbermann ad90a67439 [test] Assert on stable error codes (#84671)
Fixes
```
DevErrorOverlay › sends feedback when clicking not helpful button

    expect(received).toEqual(expected) // deep equality

    - Expected  - 1
    + Received  + 1

      Array [
    -   "/__nextjs_error_feedback?errorCode=E794&wasHelpful=false",
    +   "/__nextjs_error_feedback?errorCode=E209&wasHelpful=false",
      ]
```

--
https://github.com/vercel/next.js/actions/runs/18360913450/job/52306369449#step:34:793
2025-10-09 00:20:13 -07:00
Wyatt Johnson d81ef2691c feat(breaking): Hard Deprecate PPR Configuration (#84280)
This hard deprecates the `experimental.ppr` configuration, requiring
users to opt-in instead via `experimental.cacheComponents`. This does
mean that the previous `experimental.ppr = "incremental"` will no longer
be supported.

NAR-433
2025-10-08 19:55:52 -06:00
Ben Gubler 41e39426eb Remove automatic linting from build (#83136)
### What?
This PR removes the automatic ESLint linting that previously ran during `next build`. The documentation has been updated to reflect this change.

### Why?
As part of Next.js 16, we're removing the automatic build-time linting that was previously included in the build process. This gives developers more control over when linting runs by explicitly invoking their linter via npm scripts.

### How?
- Updated documentation to clarify that automatic build-time linting has been removed in Next.js 16
- Removed the `runLint` parameter and related linting code from the build process
- Removed the `verifyAndLint.ts` file which is no longer needed
- Simplified type checking code by removing lint-related functionality
- Removed ESLint telemetry during builds
2025-10-08 16:35:07 -07:00