Scope all `serverActions` config in one group "serverActions" to make it
more semantics
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Rather than sending a warning, we should fail the build if a postpone
call is caught. We should also fail the build if there are any errors
during static generation similar to the non-ppr case.
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
### What?
Adds support for Server Actions imported by both server and client.
### Why?
If an Action is imported by both the Client and RSC layers, we need to
support them as if they're the same action.
### How?
First, we need to ensure both layers create the same action hash ids,
which we can then use to deduplicate actions imported by both layers. If
a conflict is found, we prefer the RSC layer's action.
Closes WEB-1879
---------
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
when calls to `maybePostpone` throw but there's no postpone state, we want to handle those errors differently so that we can provide clearer messaging around how to prevent them, while still retaining any errors that were re-thrown by the user.
ex:
![CleanShot 2023-10-25 at 16 05 56@2x](https://github.com/vercel/next.js/assets/1939140/d86cce9f-f9ed-477d-8d1c-0ce7c934d073)
Apply react-server condition and related API checks for pages API.
if you're doing react SSR with renderToString in middleware it should be disallowed. Imaging it could send the rendered html code to client and you display it in browser. But it might require hydration so it can be broken.
Follow up for #57448 , same reason explained in #57448
Closes NEXT-1653
## Story Time
Metadata API introduced two exports `metadata` and `generateMetadata` to the pages and layouts under app router, as partial prerendering work is going on and people are desiring to render the metadata asynchronizly, this change will be the preparation for moving to the dynamic & asynchronized land. In short, if we can render the metadata asynchronizedly, it will benefit the performance of the initial page loading and client page transiation a lot. Any slow data fetching can be handled while the essential page "shell" is rendered.
For meta tags, there're few ones will visually affect your web page, such as `<meta name="viewport">`, `<meta name="theme color">` and `<meta name="color-scheme">`, rendering them lately after the page frame is ready might bring flickering to the page such as revreting whole page's theme color or shaking due to viewport updates. Those meta are not majorly the "metadata" for SEO, but more for user experience when opening the page. If we're rendering everything as async meta tags, it won't be ideal due to the flickering on your web pages.
## Solution Preparation
We'll want to render the meta tags separately to make sure the visual ones are rendered as blocking along with web page, and then the ones for SEO or bots can be flushed later by later, like a suspense boundary keeps emitting them into the head of html.
We optionally picked up 3 meta tag "viewport", "theme-color" and "color-scheme" to be render first into the web page with html "shell", to guarantee the layout viewport and basic styling are rendered first.
This PR introduced two module export in the page and layout files: `viewport` and `generateViewport`, in order to separate the visual meta tags from the SEO metadata.
### API
```ts
// page.js | layout.js
export const viewport = {
// viewport meta tag
width: 'device-width',
initialScale: 1,
maximumScale: 1,
interactiveWidget: 'resizes-visual',
// visual meta tags
colorScheme: 'dark',
themeColor: { color: 'cyan', media: '(prefers-color-scheme: dark)' },
}
```
There's also a dynamic API like what we did for metadata API
```ts
// page.js | layout.js
export function generateViewport() {
return { ... }
}
```
## Notice
This PR won't get SEO metadata rendered asyncronizedly, instead it's a preparation for the later work in partial prerendering and async metadata. We'll encourage the Next.js community moving to the new metadata viewport API if you're customzing those 3 meta tags. Usually you don't have to change viewport itself, so mostly like only theme-color and color-scheme could relate to it.
Instead of `Readable.toWeb` we're gonna manually convert the Node.js stream to a Web stream. `toWeb` is either having a bug, or not compatible with middleware-cloned `PassThrough` streams.
Closes#56286. The case should be already covered with existing tests.
This ensures when an error occurs during a revalidate in app router that
properly throw the error fully and don't store the error page in the
cache which matches the expected behavior for full route ISR as errors
are not meant to update the cache so that the last successful cache
entry can continue being served.
Fix was tested against the provided reproduction here
https://app-dir-example-ghl01cxtn-basement.vercel.app/
Fixes: https://github.com/vercel/next.js/issues/53195
This ensures we don't unexpectedly error when a fetch attempts to cache
inside of `unstable_cache`, this also ensures `only-on-store` doesn't
unexpectedly error when `revalidate: 0` is set.
This PR introduces a build optimization to create a "partial prerender" of the page.
1. During compilation, we create a static shell for the page using your existing Suspense boundaries. Components that can be static will be included in this static shell, leaving holes for the dynamic components.
1. Using `<Suspense />`, we can define fallbacks to be included in the partial prerender, as well as the holes for the dynamic components to stream into.
This means Next.js can initially serve a static loading skeleton, kicking off the dynamic parts in parallel. Then, the dynamic components stream in on demand. Dynamic components can use `cookies()`, `headers()`, `'cache': 'no-store'`, or `unstable_noStore()` to opt-into dynamic rendering.
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
We introduced a data fetching logging before, and the control option was under experimental. After a bit experiments turns out users really loves it. We decide to move it to a stable option.
### Changes
We're going to move the `logging` option outside of `experimental`, and scope the `fetches` related config under `logging.fetches`.
```js
// next.config.js
logging?: {
fetches?: {
fullUrl?: boolean
}
}
```
### What?
- fixes test 17553c5e25/test/e2e/app-dir/metadata/metadata.test.ts (L487)
The way next.js collects static metadata is read static metadata, and then read layout metadata to merge multiple metadatas into a single layout path (17553c5e25/packages/next/src/lib/metadata/resolve-metadata.ts (L347-L352))
When turbopack creates LoaderTree for the corresponding directory tree, it extracts `page` but skips metadata in result there are orphan components that have a metadata doesn't have layout metadata, as well as a component have a layout doesn't have metadata. Latter is being rendered as a page (since it have correct layout), which eventually falls back to the default metadata instead.
PR trickles down the metadata when extracting page (creating a new component with `page`) to consolidates those.
Also PR expands Metadata to have base_page property to capture where it has been originally exists, as we clone down metadata then do `fillMetadataSegment` against the current page where LoaderTree is being created it creates a wrong relative path. For example, currently
```
/icon.svg
- opengragph/
- static -> path being `/opengraph/.../icon.svg` instead of `/icon.svg`
```
When recursively traverse directory tree, capture each components with corresponding base_page to calculate instead.
Unfortunately this doesn't make pass all of the metadata tests; there are lot to dig more. Would like to scope PR in a reasonable size.
Closes WEB-1795
This PR implements encryption and decryption for Server Action bound values that are from the closure level. Explicit `.bind` values, function arguments and module-level values are NOT handled.
### Compiler
The compiler now groups all closure bound values to an array which gets wrapped with `encrypt`. And then inside the action body, it prepends an expression to recreate the values via `await decrypt`.
Since closure-closed variables will only exist on the server layer, the encryption utility has `"server-only"` annotated.
### Encryption
During build time, a private AES-GCM encryption key is randomly generated and stored in the built server manifest. Before encrypting/decrypting, an extra round of Flight server and client will be used to serialize/deserialize the value.
When encrypting, a salt that contains the action ID is provided to prevent replay attack towards different API endpoints. The encryption key can be overridden via the `NEXT_SERVER_ACTIONS_ENCRYPTION_KEY` env variable so it can be built on multiple machines on scale.
A global singleton for storing the client reference manifest was made for Flight's serialization/deserialization as that might happen outside of rendering.
After encryption, we then serialize the ArrayBuffer as Base64 to send it to the client.
Remove the experimental `serverActions` flag
Co-authored-by: Shu Ding <3676859+shuding@users.noreply.github.com>
Co-authored-by: Jiachi Liu <4800338+huozhi@users.noreply.github.com>
Exposes the new experimental Taint APIs using the `taint` flag which
enables experimental React.
As an example for how we can use it, I use it to taint `process.env`
with a better error message. I'm not sure where this should live since
it's a global init but it needs access to the global config. It's
unnecessary to retaint it for every render but not sure if there's a
better place for it.
---------
Co-authored-by: Jimmy Lai <laijimmy0@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
We already had `domains` as "not recommended" but this PR marks it as "deprecated" and prints a warning if its detected.
I also updated all examples to switch from `domains` to `remotePatterns`.
### Story
Since we introduced `ImageResponse` into `next/server` export, there're a few libraries relying on `next/server` that accidentally ended up with bundling og image into the bundle. As og package is quite large that could easily raise the size concern for middleware, edge runtime routes.
### Struggles
We've done optimizations. The tree-shaking strategies are tricky, we tried modularize imports and also optimize cjs require/exports to make sure you're not including og package into bundle if it's not being used. However, it's still not 100% can handle all the bundle optimization cases, such as `import {..} from "next/server.js"` could also ended up with the cjs bundle that failed the tree-shaking.
### Move on
So we decide to move og `ImageResponse` into a separate export `next/og`
Closes NEXT-1660
This PR adds the optional `limit` parameter on String.prototype.split uses.
> If provided, splits the string at each occurrence of the specified separator, but stops when limit entries have been placed in the array. Any leftover text is not included in the array at all.
[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split#syntax)
While the performance gain may not be significant for small texts, it can be huge for large ones.
I made a benchmark on the following repository : https://github.com/Yovach/benchmark-nodejs
On my machine, I get the following results:
`node index.js`
> normal 1: 570.092ms
> normal 50: 2.284s
> normal 100: 3.543s
`node index-optimized.js`
> optmized 1: 644.301ms
> optmized 50: 929.39ms
> optmized 100: 1.020s
The "benchmarks" numbers are :
- "lorem-1" file contains 1 paragraph of "lorem ipsum"
- "lorem-50" file contains 50 paragraphes of "lorem ipsum"
- "lorem-100" file contains 100 paragraphes of "lorem ipsum"
This updates some code related to web streams and encoding.
- Removes some unused code related to base64 encoding/decoding (Edge runtime currently supports it natively via `Buffer`)
- Prefer readable stream `pull` versus `.on("data", (chunk) => { ... })` event handlers (simplifies execution)
- Utilize `pipeTo` and `pipeThrough` on web streams to remove custom code related to stream pumping
- Updates pipe readable function to utilize web streams first class rather than relying on manual pumping + stream management
- This also takes advantage of the `AbortController` when piping so that the response can use it to cancel the stream
This PR introduces a new API, `unstable_noStore`, which will allow users to declaratively opt out of caching anywhere during static generation in the same way that you can specify `cache: 'no-store'` on a fetch call in Next.js.
An important caveat and difference from just calling `cookies()` to opt-out of static generation is that this won't opt you out when called from within `unstable_cache` and instead defers to the cache configuration to it.
```
import {unstable_noStore as noStore} from 'next/cache';
export default async function Component() {
noStore();
const result = await db.query(...);
}
```
<!-- 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
### Adding or Updating Examples
- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md
### 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 #
-->
This PR therefore introduces to always set response status code to 500
unless it is a `NotFoundError` or `RedirectError`. This PR would fix
issue #56235. See also:
https://codesandbox.io/p/sandbox/nice-panini-2z3mcp .
**Current Behavior**
At the moment, when an unexpected error occurs during app server
rendering, a 200 ok is returned as status code. This seems to be
undesirable because of the success status CDNs will cache the error
pages and crawlers will index the page considering the error content as
the actual content.
**Desired Behavior**
This issue is related to discussion
https://github.com/vercel/next.js/discussions/53225. Even though I
understand that the response status code cannot be set if streaming has
started, in my view it would be best to set the response status to 500
whenever it can (so before the streaming has started) for SEO and (CDN)
http caching. This would also be consistent with how 404s currently
work; that is, response status code is set to 404 if `NotFoundError`
occurred before streaming (related
[issue](https://github.com/vercel/next.js/issues/43831) &
[PR](https://github.com/vercel/next.js/pull/55542)).
Ideally, when a runtime error happens after streaming, a `<meta
name="robots" content="noindex" />` would also be added. But I didn't
want to make the PR too complex before receiving feedback.
---------
Co-authored-by: Vũ Văn Dũng <me@joulev.dev>
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
### What?
BREAKING CHANGE: Bump the minimum required Node.js version.
### Why?
Node.js 16 has reached end-of-life in September.
Bumped to `18.18.2` since it contained some security-related patches: https://nodejs.org/en/blog/vulnerability/october-2023-security-releases
### How?
Bumped `engines` where needed, upgraded the workflows.
This will allow us to remove quite a few polyfills, I'll open separate PRs for those.
Since Turbopack doesn't use eval-source-map the CSP nonce will pass correctly, nice improvement over the current state where you can't check CSP in dev.
Fixes a bunch of the Turbopack test failures for `test/e2e/app-dir/app/index.test.ts`. Not sure how this passed with webpack before as the dep was indeed missing.
### What?
Adding back `x-forwarded-*` headers.
### Why?
Starting with #52492, these headers were lost.
### How?
We can populate these headers before executing a request.
Closes NEXT-1663
Fixes#55942
`useParams` is not referentially equal between renders which can lead to unexpected behavior when used as a dep.
This memoizes the response from `useParams` similar to `useSearchParams`.
[slack x-ref](https://vercel.slack.com/archives/C04DUD7EB1B/p1697145987740229)
This change is to pick the esm assets for RSC server layer and server rendering side, this is for production and development perf purpose, also to let them apply with the ESM related optimization such as tree-shaking, barrel files optimizations, etc.
We found a few packages that can't be optimized easily in bundling because we're using "main" field so the packages are not able to be tree-shaked, ending up with large bundle in the dist. This will change a lot for the bundling improvements as some packages are only having "main" and "module" field. So switching from CJS to ESM means better bundling, more optimization, and faster code.
#56501 was a precondition for this, as previously the bundling strategy was applied to some library but triggered the invalid hooks erroring.
### Other Monior Change
Previously we'll prefer to resolve CJS as there're 2 versions of react, using CJS assets will help let them pass by require-hook to use canary react for app router bundling assets. But now we changed the approach to bundling nextjs runtime and react packages. Now we dropped the condition that prefered to resolve CJS exports for externals, since if you're putting them in `serverComponentsExternalPackages`, they're not using the built-in react, so could potentially having trouble if any dependency is using react but excluded in bundles. So far we didn't see any report to this.
Closes NEXT-1286
This applies the predefined list of packages in server-external-packages.json as always external when used by app router in Turbopack
Test Plan: Added integration tests
Closes WEB-1709
There should be no shared react packages in our server runtime. rsc should always be separate from ssr.
This update reconfigures the runtiem to eliminate shared react modules. the jsx runtime will now be separate for RSC and SSR. this is necessary because the implementations for the jsx runtime rely on React and they need to see the right versions.
Additionally I fixed an alias so that the shared subset react is used when using react-server condition.
I also fixed a bug in 2 tests related to class/className.
Note: this PR blocks upgrading React canary due to internal changes in how React state is managed in when using the `react-server` condition