## Summary
**What?** Fixes the error reported for a module that has a top-level
`"use client"` directive and an inline `"use server"` function
directive, e.g. `<form action={async () => { "use server" }} />` in a
client page.
**Why?** Under Turbopack this reported a bogus error — `The "use client"
directive must be placed before other expressions` — even though the
directive was already at the top of the file. The actual mistake (an
inline server action inside a Client Component) was never surfaced.
**How?** On Turbopack's RSC layer the server actions transform runs
*before* the React Server Components assert. When it hoists an inline
action it prepended its generated imports (`registerServerReference`,
action encryption, cache runtime) at index 0 of the module — *above* the
`"use client"` directive, which the transform does not consume. The RSC
assert then saw an import before the directive and reported it as
misplaced.
Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Adopts #97150. Closes#97150.
Fixes#96859
### What?
Since 16.3.0, builds fail for pages-router files named `sitemap` or
`robots` that export `getStaticProps`/`getServerSideProps`:
```
Error: "getStaticProps" is not supported in app/.
```
This is a regression from #94962, which added the metadata conventions
(`sitemap`, `robots`, `manifest`, `icon`, …) to the app-entry filename
regex in `ReactServerComponentValidator::assert_invalid_api`. The regex
only looks at the filename, so a file like `pages/sitemap.js` is now
mistaken for an app entry and rejected for exporting `getStaticProps`.
### How?
A file is only treated as an app entry when it's inside `appDir`,
reusing the gate `assert_server_filename` already applies to `error.js`.
The pages compilation context has no `appDir`, so pages-router files are
never validated as app entries.
On the test side:
- The fixtures that exercise the app-entry checks moved under
`app-dir/`, since the test harness derives `appDir` from the fixture
path. Their contents are unchanged.
- A new fixture (plus a `sitemap.js` fixture glob) asserts that a
pages-style `sitemap.js` compiles without errors.
- A new e2e suite, `test/e2e/pages-metadata-filenames`, covers
`pages/sitemap.js` with `getStaticProps` and `pages/robots.js` with
`getServerSideProps`. It fails without the fix under Turbopack (build
and dev) and passes with it under both Turbopack and webpack.
Supersedes #96873 (same approach, closed by its author) and closes
#96967.
---------
Co-authored-by: Rodrigo Arias <rodrigo@arias.me>
The `wasm` and `next-custom-transforms` crates were still on Rust edition 2018 while the rest of the crates in this repo use edition 2024. This caused a pre-commit hook conflict:
- `cargo fmt` passes the crate's own edition (2018) to `rustfmt`, which uses **case-insensitive** import sorting
- The lint-staged pre-commit hook runs `rustfmt --edition 2024 --`, which uses **ASCII order** import sorting (uppercase before lowercase)
These two sort orders disagree on items like `{custom_before_pass, TransformOptions}` vs `{TransformOptions, custom_before_pass}`, causing an infinite flip-flop: every commit would reorder imports, and the next `cargo fmt` would reorder them back.
## Changes
- Bump `crates/wasm` and `crates/next-custom-transforms` from edition 2018 to 2024
- Add `+ use<C>` precise capturing to `server_actions()` return type to satisfy edition 2024's stricter `impl Trait` lifetime capture rules
- Add `style_edition = "2024"` to `.rustfmt.toml` as a safety net so `cargo fmt` uses 2024-style formatting regardless of individual crate editions
- Reformat all affected files with `cargo fmt`
- Apply new clippy rules
The transform output for 'use cache' uses `Object.defineProperty` and
`Array.prototype.slice`. In theory, it's possible for a module to shadow
those names and break it:
```ts
// i want to suffer!
const Array = {}
const Object = {}
async function cached() {
"use cache"
...
}
```
We should defensively make sure that our transform's output refers to
the actual Object/Array builtins, not whatever's in scope for that name.
We can do this by using an unresolved syntax context for the
identifiers. This is what we do for `require()` elsewhere:
https://github.com/vercel/next.js/blob/6805af48baf1128e6b2a9e8f1752ee5982f02c60/crates/next-custom-transforms/src/transforms/track_dynamic_imports.rs#L119-L122
Using `quote_ident!(unresolved_ctxt, "Array")` will cause SWC to rename
any local redefinitions of `Array` to something that doesn't clash
(which can be seen in the added snapshots).
Using `taint` APIs from React without enabling `experimental.taint` will
error at runtime because it needs to bundle experimental React, making
it hard to catch and potentially leading to downtime. This updates our
transform to throw an error if we detect that it's imported but `taint`
isn't enabled.
Fixes NAR-690
Upgrade swc from 45 to 48
Based on #85540
- In the AST, strings now contain a `Wtf8Atom` (= not utf8), while `Ident`s keep using the utf8 `Atom`.
- swc's comment printing logic also changed slighted, moving some comments around
- ~~Some comments are getting lost along the way and/or attached to the wrong line. This also broke server actions which rely on a `__next_internal_client_entry_do_not_use__` at the very top~~
When functions exported from a module with a top-level `'use cache'`
directive are imported into client modules, the compiler should allow
`cacheLife` and `cacheTag` usage within those functions.
This PR updates the `react_server_components` transform to properly
track module directives (`'use client'`, `'use server'`, `'use cache'`)
and skip client graph validation for modules with `'use cache'`,
identical to how modules with `'use server'` are already handled. Those
modules are transformed anyway for the client graph by the
`server_actions` transform, which is applied after the
`react_server_components` transform, in which their implementation is
replaced by server function references.
closes NAR-498
Importing `cacheLife` and `cacheTag` in Client Components yields build errors. This adds test fixtures to cover these scenarios.
In addition, we're duplicating the test fixtures that have different error messages between `app/` and `pages/` directories to ensure both cases are covered.
Replace construction of `RcStr` instances on constant strings with the `rcstr!` macro which can shift construction costs to compile time and eliminate reference counting.
Performance impacts from all the dropped ref counts are minor but do exist

There is also a small progression in max heap which makes sense, laying out the static rcstrs should be a somewhat easier job compared to mimalloc.
## What?
Rename `experimental.dynamicIO` to `experimental.cacheComponents` across
the Next.js codebase.
## Why?
We're going to be merging the functionality of the `ppr`, `dynamicIO`
and `useCache` experimental flags into the singular `cacheComponents`
flag to reduce complexity of the codebase and simplify adoption for
users wanting to experiment with experimental features.
## How?
- Renamed the configuration option from `experimental.dynamicIO` to
`experimental.cacheComponents`
- Added deprecation handling with automatic migration for the old option
name
- Updated all documentation, tests, and internal references
- Updated Rust code in SWC transforms and Turbopack
- Maintained backward compatibility with deprecation warnings
NAR-158
Closes PACK-4074
We really need to look into getting e2e tests for correct sourcemaps: PACK-4142
Fix Turbopack server action tree shaking by explicitly splitting up that module
```js
/* __next_internal_action_entry_do_not_use__ {"00c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","70e10665baac148856374b2789aceb970f66fec33e":"myAction"} */ import { createServerReference, callServer, findSourceMapURL } from "private-next-rsc-action-client-wrapper";
export var foo = /*#__PURE__*/ createServerReference("70e10665baac148856374b2789aceb970f66fec33e", callServer, void 0, findSourceMapURL, "myAction");
export var bar = /*#__PURE__*/ createServerReference("00c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", callServer, void 0, findSourceMapURL, "default");
```
->
```js
"use turbopack no side effects";
export { foo } from "data:text/javascript,%2F%2A%20__next_internal_action_entry_do_not_use__%20%7B%2200ab21efdafbe611287bc25c0462b1e0510d13e48b%22%3A%22foo%22%7D%20%2A%2F%22use%20turbopack%20no%20side%20effects%22%3Bimport%7BcreateServerReference%2CcallServer%2CfindSourceMapURL%7Dfrom%22private-next-rsc-action-client-wrapper%22%3Bexport%20var%20foo%3D%2F%2A%23__PURE__%2A%2FcreateServerReference%28%2200ab21efdafbe611287bc25c0462b1e0510d13e48b%22%2CcallServer%2Cvoid%200%2CfindSourceMapURL%2C%22foo%22%29%3B";
export { bar } from "data:text/javascript,%2F%2A%20__next_internal_action_entry_do_not_use__%20%7B%2200ac840dcaf5e8197cb02b7f3a43c119b7a770b272%22%3A%22bar%22%7D%20%2A%2F%22use%20turbopack%20no%20side%20effects%22%3Bimport%7BcreateServerReference%2CcallServer%2CfindSourceMapURL%7Dfrom%22private-next-rsc-action-client-wrapper%22%3Bexport%20var%20bar%3D%2F%2A%23__PURE__%2A%2FcreateServerReference%28%2200ac840dcaf5e8197cb02b7f3a43c119b7a770b272%22%2CcallServer%2Cvoid%200%2CfindSourceMapURL%2C%22bar%22%29%3B";
````
- [x] Keep [sourcemaps](https://github.com/vercel/next.js/blob/canary/test/development/app-dir/source-mapping/README.md#server-actions)
The `"use cache"` directive is not compatible with the Edge runtime.
When the `experimental.useCache` flag is enabled, we now emit a build
error for pages with `export const runtime = 'edge'`. This is analogous
to using the `experimental.dynamicIO` flag.
The other route segment configs that are forbidden when `dynamicIO` is
enabled, are currently still allowed for `useCache`:
- `dynamicParams`
- `dynamic`
- `fetchCache`
- `revalidate`
The issues with the current export statement validation for app router
pages are documented in the added fixtures, see also the inline comments
in the diff.
We’re updating the SWC transform to
[track](https://nextjs.org/telemetry) how the "use cache" directive is
used during builds. Each use of "use cache" is counted based on the
handler it’s linked to.
By default, "use cache" counts toward a feature called
"useCache/default". If a custom handler is defined in the Next.js config
(e.g., "custom"), then "use cache: custom" will count toward
"useCache/custom".
The build process will collect these counts and combine them across all
source files and workers. This data is reported under the
NEXT_BUILD_FEATURE_USAGE event, allowing us to filter by "useCache/*" to
see how often each cache handler is used.
*Only support webpack prod build for now.
Closes NDX-683
When a `"use cache"` directive with a custom cache kind is used, e.g.
`"use cache: custom"`, a cache handler with the same name must be
specified in the Next.js config:
```js
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: {
dynamicIO: true,
cacheHandlers: {
custom: require.resolve('path/to/custom/cache/handler'),
},
},
}
module.exports = nextConfig
```
If this is not the case, we emit a build error with an error message
that explains this requirement.
<img width="795" alt="Screenshot 2024-11-14 at 23 30 01"
src="https://github.com/user-attachments/assets/bd138c97-608f-42ce-abb2-edb3e44edc3f">
When we'll get a docs page for this experimental config, we will add the
usual "Read more: ..." hint as well.
---------
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
Co-authored-by: Janka Uryga <lolzatu2@gmail.com>
After adding validation that fixing invalid segment configs (when DIO is
enabled), it revealed that errors weren't being displayed in Turbopack,
because `setHMRServerError` wasn't implemented.
This refactors the implementation to use the existing server component
transform when validating if the segments are valid. This has the
benefit of highlighting precisely where the segment is coming, making it
easier to remove. The test that was skipped in Turbopack is also
re-enabled.
<details>
<summary>Screenshot</summary>

</details>
This adds an extra `hash_salt` option to the Server Actions transform's
`generate_action_id` method which defaults to empty for now (so no
actual behavior changes). When set, the salt will be used to prefix the
payload.
### What?
Revert swc_core upgrade, as it has a bug related to `styled_jsx`
transform.
Wasm plugin version runs after the TypeScript pass so it works, but
custom transform (next-swc) runs before the typescript pass so it
breaks.
### Why?
It broke some apps.
### How?
### What?
Removes the `turbopack-binding` crate which is unnecessary now that we
have everything in one repo.
This should improve compile times a bit.
Closes PACK-3162