This ensures we use the correct `srcPathname` in minimal mode so that we
can normalize the URL and generate the correct `ssgCacheKey` which is
used for request caching/de-duping.
We aren't able to add a reliable test case for this as it is a race
condition within a second of a previous request although this was
verified against a stress test repro here
https://overlapping-segments-h1455lwvk-vtest314-ijjk-testing.vercel.app/repro/tutorials/demo
This behavior seems to have regressed in
https://github.com/vercel/next.js/pull/45716
Closes NEXT-1777
### What?
When using a server action on an intercepted route, when submitting that
action, you'd expect it to correspond with the page you're currently on.
However if you have route interception set up, and you load the page
rather than the intercepted page, submitting the action would `POST` to
the intercepted page. This would result in a 404 error because the
action ID you're attempting to submit wouldn't be found on the requested
page.
### Why?
Interception routes rely on the `Next-Url` request header to determine
if an interception should occur via a rewrite. However, server actions
are submitted with this header as well, so the rewrite will be applied
to the `POST` request corresponding with a non-existent action, or an
action on the intercepted page.
### How?
When loading a page that has an intercepted route, `nextUrl` should be
consistent with URL derived from the flight router state tree. But when
an interception occurs via navigation, `nextUrl` will now deviate. I'm
using this to determine whether or not `Next-Url` should be forwarded
along in the `POST` request.
Closes NEXT-1436
Fixes#52591Fixes#49934
### What?
When using rewrites, in the scenario where a user visits an intercepted
route, reloads the page, goes back, and then revisits the same route, we
serve the page rather than the intercepted route.
### Why?
#59094 fixed the case where `ACTION_RESTORE` was not restoring `nextUrl`
properly. However there's a separate issue where when the `SERVER_PATCH`
action comes in, `handleMutable` attempts to compute `nextUrl` by
comparing the patched tree with the current tree. In the case of the
popstate event, both trees are the same, so the logic is currently
configured to fallback to `canonicalUrl`, which is not the correct URL
to use in the case of rewrites.
### How?
If the computed changed path is null, we should only fallback to using
`canonicalUrl` if we don't have a valid `nextUrl` that we can use.
Closes NEXT-1747
Fixes#56072
## What?
While investigating a Turbopack bug we noticed that middleware would be
skipped in development if there was an error during compilation that
caused `ensurePage` to throw. This updates the logic to not catch that
throw and instead make it bubble up correctly.
<!-- 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 #
-->
**Note**: this is a 1-to-1 copy of #48969 by @danieltott with all the
merge conflicts fixed.
## Checklist
* Fixes https://github.com/vercel/next.js/issues/48966
* Tests added to
`test/production/app-dir/subresource-integrity/subresource-integrity.test.ts`
## Description
Currently `renderToHTMLOrFlight` in app-render pulls out a nonce value
from a `content-security-policy` header for use in generating script
tags:
e7c9d3c051/packages/next/src/server/app-render/app-render.tsx (L1204)
That misses the ability to use a [content-security-policy-report-only
header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only).
Many times this is a required step to enabling a CSP - by shipping a CSP
with report-only and collecting reports before actually blocking
resources.
## Changes
* Added ability to check `content-security-policy-report-only` header in
`renderToHTMLOrFlight()`
* Added test to verify `nonce` is correctly applied when
`content-security-policy-report-only` header exists
Co-authored-by: Dan Ott <dan@dtott.com>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
If a manual signal handler is registered, SIGINT and SIGTERM should not
be handled by Next.js. This was already the case in the standalone
server.js but was missing here, rendering the env flag useless.
With this fix, the example given in
https://nextjs.org/docs/pages/building-your-application/deploying#manual-graceful-shutdowns
is working (again).
Fixes#56810.
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
When using `experimental.typedRoutes` in conjunction with
`experimental.webpackBuildWorker`, type errors would be erroneously
thrown during build.
This is because the build workers are parallelized between multiple
runtimes (edge, server, client), but the `typedRoutes` is unique to each
`webpackBuild`. The state needs to shared between the different compile
steps for each instance of the types plugin.
This leverages plugin state to keep share the `typedRoutes` state
amongst the different workers.
Closes NEXT-1734
Fixes#58369
This ensures we don't spam build logs with dynamic usage errors or
similar unexpectedly as they can be caught by this worker process
listener but shouldn't be logged.
Closes NEXT-1763
This:
- Sends an hmr sync event so that errors that occur after the initial
hmr connection are sent to the client
- Aligns on `path/to/file.js:line:column` format across error overlay
implementations in the cli and on the web
- Adapts "Module not found" errors from Turbopack to include
Next.js-relevant formatting and documentation links to align with
webpack
Test Plan: Passes 3 tests that were previously failing
Closes PACK-1974
---------
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: Leah <github.leah@hrmny.sh>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
### What?
When using interception routes & rewrites, on first interception the
router will properly handle the request. But when using the back button
and attempting another interception, it won't work
### Why?
Intercepting routes rely on the accuracy of `nextUrl` -- but when
`ACTION_RESTORE` is dispatched (in the `popstate` event), `nextUrl` is
restored from `url.pathname` rather than the flight router state.
### How?
This uses the `extractPathFromFlightRouterState` util which will
properly handle setting `nextUrl`. This util is also used when creating
the initial router state.
Closes NEXT-1747
Fixes#56072
### What?
When handling a server action, in the non-progressive enhanced case,
React will attempt to parse the request body before verifying if a valid
server action is received. This results in an "Error: Connection Closed"
error being thrown, rather than ignoring the action and failing more
gracefully
### Why?
To support progressive enhancement with form actions, the `actionId`
value is added as a hidden input in the form, so the action ID from the
header shouldn't be verified until determining that we've reached the
non-PE case. ([React
ref](https://github.com/facebook/react/pull/26774)). However, in
https://github.com/vercel/next.js/pull/49187, support was added for a
URL encoded form (which is not currently used, as indicated on the PR).
Despite it not being used for server actions, it's currently possible to
trigger this codepath, ie by calling redirect in an action handler with
a 307/308 status code with some data in the URL. This would result in a
500 error.
### How?
React should not attempt to parse the URL encoded form data until after
we've verified the server action header for the non-PE case.
x-ref NEXT-1733
[Slack
context](https://vercel.slack.com/archives/C03S8ED1DKM/p1700674895218399?thread_ts=1700060786.749079&cid=C03S8ED1DKM)
### What?
A `redirect` that occurs during a fetch action will get a status code of
200, while the redirection logic is handled client-side.
### Why?
In this scenario, the redirect is handled by the client router, so no
`Location` is set on the action response. However for debugging /
logging purposes, it'd be useful to still return the same status code
used in other cases (see #58885)
### How?
Rather than selectively setting the status to 303 in the non-fetch
action case, this always applies it.
Closes NEXT-1745
If a build time fetch cache is present from a previous build we don't
want to unexpectedly use it when flush to disk is set to false in a
successive build as it can leverage stale data unexpectedly.
x-ref: [slack
thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1701266754905909)
Closes NEXT-1750
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
### What?
Calling `redirect` or `permanentRedirect` with a route handler used by a server action will result in that POST request following the redirect. This could result in unexpected behavior, such as re-submitting an action (in the case where the redirected URL makes use of the same server action).
### Why?
By spec, 307 and 308 status codes will attempt to reuse the original request method & body on the redirected URL.
### How?
In all cases when calling a `redirect` handler inside of an action, we'll return a `303 See Other` response which is a typical status code when redirecting to a success / confirmation page as a result of a POST/PUT.
The other option would be to use 301 / 302 status codes, but since we're already doing a 303 status code [here](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/action-handler.ts#L603), this aligns the behavior for the route handler case.
Closes NEXT-1733
See also: https://github.com/vercel/next.js/issues/51592#issuecomment-1810212676
[Slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1700060786749079)
fixes: #58909
x-ref: #58321, #56472, #56231
Removed the Math.round of age since it can cause stale fetch data to be
considered not stale if the age rounds downwards. (5.49 is rounded to 5)
Note: This most likely also fixes some bugs with
revalidateTag/revalidatePath. Tested some tag/path issues that got fixed
with this change.
I think this is because revalidatetag/path sets [data.revalidatedAt =
Date.now()](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/incremental-cache/file-system-cache.ts#L120)
for file-system-cache. And with the current code that value would
continue to be "not stale" for up to 0.499 ms.
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
Providing better feedback loop for next bindary.
Some users with old node.js version are seeing `performance` is not defined in #57385, we should check the version first.
For compilation, `performace.mark` will also be compiled after those imports since they're hoisted as ESM. This PR moves performance profiling after the `--help` and `--version` processures and node.js version check. So users can see the "upgrade node.js" hint if the node.js version is too old instead of "performance is not defined"
### What?
When the router action queue receives a bunch of async actions in quick succession, some of those requests are dropped, and as a result, anything observing pending transitions will be stuck in a pending state.
### Why?
When adding items to the action queue, the intended behavior is for new actions to be added to the end of the action queue, to be picked up by `runRemainingActions` once the in-flight action is processed. However, new actions are erroneously overwriting pending actions in the queue rather than appending them, as `actionQueue.last` might have a pending action attached to it.
### How?
This moves the assignment of `actionQueue.last` to always be in `dispatchAction`, rather than the function that processes the action, so that we always have a single spot where `last` is assigned and to prevent it from erroneously omitted/overwritten.
Fixes#59011
### What?
Bump up turbopack which includes url rewrite related improvements. This makes `test/integration/url` test passes.
Note there are some lacking behavior around edge runtime + url behavior, it is being tracked in PACK-2014.
Closes PACK-2051
The rewrite request appear to bypass the `BaseServer` or are executed in
the sandbox. However, these requests have the correct test info in the
headers that can be used instead of the `AsyncLocalStorage`.
This improves some of the typings around the `RenderResult` returned during renders. Previously it had a single large metadata object that was shared across both the pages and app render pipelines. To add more type safety, this splits the types used by each of the render pipelines into their own types while still allowing the default `RenderResult` to reference metadata from either render pipeline.
This also improved the flight data generation for app renders. Previously, the promise was inlined, and errors were swallowed. With the advent of improvements in #58779 the postpone errors are no longer returned by the flight generation and are instead handled correctly inside the render by React so it can emit properly postponed flight data.
Besides that there was some whitespace changes, so hiding whitespace differences during review should make it much clearer to review!
### What?
We currently dedupe fetch requests, but if those fetch requests contain a `revalidate` time, when that window is expired all of those fetches will be invoked without deduping.
### Why?
We track revalidations on the `staticGenerationStore` but we don't have a way to dedupe them, as it's currently just an array. When the (patched) fetch is invoked and catches a stale entry, it'll push each fetch onto the `pendingRevalidates` array which will later be invoked via `Promise.all`.
### How?
This updates the shape of `pendingRevalidates` to be a map, that way we can reliably dedupe if we see a key that is already pending revalidation.
Closes NEXT-1744
[slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1700836529460289)
### What
Pairing with https://github.com/vercel/turbo/pull/6602, enables
ecma-related transform support in mdx. notably fixes test cases in
https://github.com/vercel/next.js/pull/58968 .
With turbopack side fix, still modularize imports are not being applied
as we limite it to .js* extension only. PR expands it to include mdx if
mdx is enabled. PR is failling until turbopack side fix lands.
Closes PACK-2045
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Utils `stringToUint8Array` and `arrayBufferToString` assume that the values are just arbitrary fixed width data. However that doesn't work when we do unicode concatenation (`actionId + arg`) which requires Text encoder/decoder to be used.
Closes#58463, closes#58579. In general any complex unicode characters will cause the same issue, for example emojis.
## What?
Was investigating an issue with Turbopack and MDX, in the process found
a few bugs:
- When you have a `tsconfig.json` or `jsconfig.json` the `baseUrl: '.'`
is used by default which causes the top-level directories to be
available as e.g. `design-system` (without a prefix).
- This is not how TypeScript's default setting for `baseUrl` works.
While it should resolve `paths` relative to `.` when none is specified
it does not do additional resolving for the top level directories/files.
- When `"baseUrl": "."` is added to `tsconfig.js` explicitly it handles
the top level directories.
- `modularizeImports` and other SWC transforms weren't applied to `.mdx`
files when `experimental.mdxRs` is enabled, which caused compilation to
fail.
- `modularIzeImports` and other SWC transforms are not applied to `.mdx`
files when using Turbopack.
- @kwonoj is investigating this, will be handled in a follow-up PR.
## How?
- Added a test suite for `modularizeImports` with MDX tests
- Removed the condition that disables swcLoader in webpack when using
mdxRs
- Changed the check for `tsconfig.json` / `jsconfig.json` baseUrl to
include if it was implicitly or explicitly set, disabled the module
resolving when it is implicitly set
<!-- 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 #
-->
---------
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
There're some reports related to using incorrect Node.js version, sometimes users ended up in weird errors. As pkg manager like pnpm only gives a warning ` WARN Unsupported engine: wanted: {"node":">=18.17.0"} (current: {"node":"v16.18.0","pnpm":"8.9.0"})` which is not easy to investigate the issue.
We're adding a version check at the beginning of the Next.js process so if Node.js version is mis-match the version specified in package.json, bail with error.
Examples
node 16.x
```
You are using Node.js 16.18.0. Node.js >= v18.17.0 is required.
```
node.18.16
```
You are using Node.js 18.16.1. Node.js >= v18.17.0 is required.
```
The app router reducer state used to be managed by `useReducer`, so it
was written to be resilient to rebasing — the same action may be
processed multiple times. Now that we've lifted the reducer outside of
React (#56497), each action runs only a single time. So we can simplify
some of the logic.
Previously, actions that update that cache were passed an empty cache
object as part of the action payload. Now, we can instead create these
objects on demand in the reducer.
(We should do the same for the `mutable` object, but there's a unit test
which relies on this implementation detail, so I've left that for a
separate PR.)
<!-- 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 #
-->
We previously used preloadComponent to render nested page/layouts in
parallel, but now that all layouts are passed to React at the top level
(#58669), we no longer need this special module.
A flaw of preloadComponent was that it only called the top-most
component per layout. In the new approach, React can preload non-layout
components, too.
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
In anticipation of #58885 (and to avoid adding another spot where we're checking the same headers), this unifies the logic that parses the request headers and determines if the request corresponds with a server action.
There was already some drift between the check in `base-server` and `action-handler` (unsure if this was intentional - let me know if so, in which case maybe separated handling is the better approach. I couldn't think of a good reason why it would be different, though).
Existing tests should be sufficient for testing this changeset.
No change in behavior, this just moves a util that performs the same
error digest parsing into the other file that performs similar behavior
& validation. Since splitting & parsing the digest string is a strange
operation, this keeps it close to where that happens & where it's
validated so it's easier to follow.
Since this file is imported in the same spots that we're importing the
other redirect utils, there doesn't seem to be a reason to keep them
separated.
### What?
Shows the actual request url that triggered a compilation in the console
message
### Why?
makes it easier to find accidental compilation
### How?
Closes PACK-2017
The sandboxed request processing do not share the same async context with the `BaseServer` and thus the context should be propagated independently.
Notably, the `headers` API is different in `BaseServer` (`Record<string, string | string[]>`) vs in the sandbox (`Headers`), so additionally, we have to use the right `getter`.
Co-authored-by: Leah <8845940+ForsakenHarmony@users.noreply.github.com>
* Add docs link to the warning, add codemod link to viewport docs section
* Only log the warning once after the metadata resolving process, this will avoid multiple duplicated logs showing for one page.
Closes NEXT-1723
### What?
Rewrites to an edge route currently throw an invariant rather than properly serving up the page that is rewritten to.
### Why?
The `NextRequest` object that is provided to the edge route handler contains pathname information only for the "origin" request (e.g., when visiting `/one/example` which rewrites to `/two/example`, the pathname is still `/one/example`. This hits an invariant since the route matcher is unable to find `/one/example` since it does not exist.
### How?
This updates the module wrapper to grab the pathname from the route definition rather than the request object. For dynamic segments, we extract them from `request.nextUrl` since we know that even if `nextUrl` is referencing the origin path, the parameters it has are relevant for the rewrite.
This adds the `getUtils` utility that's also used in base-server to handle the URL normalization, which also provides an interface for normalizing dynamic params from a `ParsedUrlQuery`.
Closes NEXT-1724
Fixes#48295
This PR adds more information to `.next/trace` for local development:
- Break down server startup times into setting up the dev bundler and running the instrumentation hook
- Add top level span for handling a request such as a page request, app router request, or API request
- Add span for compilation time tracking the path of the route that triggered the compilation.
- Track memory usage after every request
- Track event when server is restarted due to reaching the memory limit
Platform stats and memory usage on startup:
![Screenshot 2023-11-20 at 8 47 38 AM](https://github.com/vercel/next.js/assets/7355009/870226cc-8caa-41bd-92ae-b0025aecdee7)
Memory usage after each request:
<img width="340" alt="Screenshot 2023-11-20 at 9 16 44 AM" src="https://github.com/vercel/next.js/assets/7355009/d14279d6-35c5-45a6-b431-b485d5d14ac6">
Split server startup times into setting up the dev bundler and running the instrumentation hook:
![Screenshot 2023-11-20 at 8 46 41 AM](https://github.com/vercel/next.js/assets/7355009/eda8b16d-a784-4332-b8b1-5f0dce0611ef)
Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com>
This PR doesn't treat an instrumentation hook as a `PAGES` page which
avoids compiling `_app`, `_document`, and `_error` when compiling the
instrumentation hook.
It's too easy to change the root context and thus the `context.active()
=== ROOT_CONTEXT` it's not a reliable way to check whether the current
context is a root. A much more predictable option is to see if there's
actually an active tracing span already defined.
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This PR fixes an issue where users would try to access `req.cookies` from a route handler and be unable to read from it.
This issue was caused by `req.cookies` not opting you into dynamic behaviour, unlike `cookies()` from `next/headers`. This fixes it.
This uses styled issue titles and details introduced in
vercel/turbo#6535, which also moves "Module not found" messaging to the
title field for those issues.
Closes PACK-2013
---------
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: Leah <github.leah@hrmny.sh>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
## What?
Changes the default resolve extensions to be consistent between
server/client compilation.
Currently browser prefers `.mjs` then `.js` and the server compiler
prefers `.js` then `.mjs`.
I added that behavior back in 2018 before mjs/cjs extensions were fully
baked and many npm libraries had incorrect usage of it (PR: #5898).
In the new setup with ESM resolving in Node.js writing out the full
extension is required for `.mjs` files, meaning this "magic resolving"
of a file to `.mjs` is no longer correct. In the future we'll likely
want to remove `.mjs` from the default list of resolve extensions to
align with the Node.js ESM resolver a bit more.
For now we have to keep it in order to not break existing applications
that rely on that behavior, an example of that seems to be contentlayer.
## How?
Removed the condition and aligned it on a single list instead of
separate lists.
<!-- Thanks for opening a PR! Your contribution is much appreciated.i
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 #
-->
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
### What?
Calls to `revalidateTag` when using the data cache would sometimes be ignored. This would result in stale data being displayed even after manually triggering a revalidation.
### Why?
Revalidation calls are pushed onto a `pendingRevalidates` array and, in the case of a route handler, are awaited [here](8b11264ea9/packages/next/src/server/send-response.ts (L53-L55)).
Previously this took place as part of the former `pipeReadable` implementation ([ref](57bb52d37d/packages/next/src/server/send-response.ts (L49))) which awaited the promise before calling res.end ([ref](57bb52d37d/packages/next/src/server/pipe-readable.ts (L99-L105))). There was a subtle change in behavior here in a recent refactor that seems to cause a race between awaiting the promise and ending the response, which results in this unpredictable behavior.
### How?
This applies similar logic that used to be in the `pipeReadable` function to the new `pipeToNodeResponse` function. Namely, we plumb `waitUntil` into the writeable stream close handler and await it before calling `res.end()`.
This is a very difficult edge case to test, and as such resorted to rigorous manual testing when deployed to an environment that uses the data cache.
Fixes#52962Fixes#57632
### What?
In #57062, a deprecation warning was added for usage of `nextConfig.images.domains`. This warning was erroneously showing up for users that had an `assetPrefix` configured.
### Why?
When an `assetPrefix` specified, during assignment for `nextConfig` default values, we push to `nextConfig.images.domains` so that the user doesn't receive errors about hostnames not being configured ([Original PR](https://github.com/vercel/next.js/pull/29307)). This means people are indirectly being opted into a deprecated config, and receiving a warning because of it.
### How?
We no longer push any defaults to the deprecated config option. Additionally, this applies the same defaults handling to `remotePatterns,` as otherwise people using this new config will run into the same issue as this block was originally intended to fix.
Fixes#58074
After the changes in #58669, it's now possible for these `DynamicUsageErrors` to be caught in the streaming renderer. We didn't have any logic to handle this happening inside the existing catch block, so this adds a check for that specific error and re-throws it so that it properly bubbles to `exportPage`. `exportPage` checks the error to see if it's a `DynamicUsageError` and if so, marks the page as dynamic.
(This resolves an issue with particular scenarios hanging the build, caught by a few of our tests: [example](https://github.com/vercel/next.js/actions/runs/6949079695/job/18907597751?pr=58744), [example](https://github.com/vercel/next.js/actions/runs/6948412805/job/18904387924))
### What?
When a layout segment forces dynamic rendering (such as with
`force-dynamic` or `revalidate: 0`), navigating to sub-pages of that
layout will attempt to re-render the layout, also resulting in side
effects re-running. This means if your layout relies on a data fetch and
you render the result of that data in the layout, it will unexpectedly
change when navigating between sub-paths, as described in #57326.
As a separate issue (but caused by the same underlying mechanism), when
using `searchParams` on a dynamic page, changes to those search params
will be erroneously ignored when navigating, as described in #57075
### Why?
As a performance optimization we generate static prefetch files for
dynamic segments ([original
PR](https://github.com/vercel/next.js/pull/54403)). This makes it so
that when prefetching is turned on, the prefetch can be served quickly
from the edge without needing to invoke unnecessarily. We're able to
eagerly serve things that can be safely prefetched. This is nice for
cases where a path has a `loading.js` that we can eagerly render while
waiting for the dynamic data to be loaded.
This causes a problem with layouts that opt into dynamic rendering: when
the page loads and a prefetch is kicked off for the sub-page, it'll load
the static prefetch, which won't be generated with the same router state
as the dynamically rendered page. This causes a mismatch between the two
trees, and when navigating within the same segment, a refetch will be
added to the router because it thinks that it's navigating to a new
layout.
This also causes issues for dynamic pages that use `searchParams`. The
static prefetch will be generated without any knowledge of search
params, and when the prefetch occurs, we still match to the prefetch
generated without search params. This will make the router think that no
change occurs, and the UI will not update to reflect the change.
### How?
There's ongoing work by @acdlite to refactor the client router.
Hopefully it will be easier to re-land this once that work is finished.
For now, I've reverted the behavior as it doesn't seem to be worth the
bugs it currently causes. I've also added tests so that when we do
re-land this behavior, we can catch these subtleties.
Fixes#57326Fixes#57075
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
### What?
Various fixes in handling of externals in node.js
* add extensions to builtin externals to allow node.js ESM to work
* improve the auto-externals logic to detect more edge cases
* prepare for `esmExternals` support, but that's blocked by client
manifest missing the async flag
* currently only `esmExternals: false` is supported
### Why?
### Turbopack Changes
* https://github.com/vercel/turbo/pull/6531 <!-- Leah - fix(turbopack):
postcss should be applied to `@import`ed CSS files -->
* https://github.com/vercel/turbo/pull/6530 <!-- Tobias Koppers - fix
node.js externals -->
---------
Co-authored-by: Leah <github.leah@hrmny.sh>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
### What?
* include path and title in errors
* don't block the page for errors in node_modules
### Why?
### How?
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
## Based on #58666
*I submitted this stack as separate PRs so I could run CI but I want to
land them as a single unit. So I've left all but this last one in draft
mode. You can review them commit-by-commit.*
We render nested layouts in parallel on the server. This means we should
be able to create a CacheNode entry for every layout in the tree as soon
as the Flight response is received by the client, even before the nested
layouts have streamed in. Currently, we wait until the nested layouts
start rendering before we write them into the cache, which prevents us
from performing certain optimizations. That's because the CacheNodes are
sent as a prop to LayoutRouter; the only way to unwrap the CacheNode is
to wait for LayoutRouter to render.
In previous PRs, I updated the server to create a top-level data
structure that contains all the CacheNodes for the entire tree. This PR
updates the client side to receive the nodes and write them into the
cache.
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Currently to make inline-defined Server Actions work, the compiler hoists the actual `"use server"` function to the module level and convert the inlined function to a parentheses expression that creates a noop wrapper function and wraps it with the proxy. This works fine however expressions are still different from declarations (#57392). So there're some details that can't be aligned well.
With this change, we're going to make the compilation for the two types of inline-defined Server Actions more robust and more lightweight:
#### 1. Expressions
```jsx
const action = async () => { "use server" ... }
const action = async function () { "use server" ... }
const action = async function named () { "use server" ... }
foo={async function () { "use server" ... }}
...
```
These expressions can directly be replaced with a new expression `createActionProxy("id", hoisted_action)`. A `.bind(...)` member call can be followed if it needs to bind any variables from the closure level.
#### 2. Declarations
```js
async function named () { "use server" ... }
```
In this case, we replace all the same `named` idents to be the expression `createActionProxy("id", hoisted_action)`, and removed that function declaration.
With these changes, these will be fewer structural changes to the AST and the code is more performant.
The PR also changes it to use React's `registerServerReference` method directly instead of our in-house implementation inside `createActionProxy`.
Another small change is to stabilize the comment header to use `BTreeMap` inside the SWC transform. Otherwise the test snapshots will randomly mismatch.
Closes#57392.
## What?
Enables `experimental.windowHistorySupport` support for Turbopack.
## How?
Turbopack has a guard for unknown options (allow-list). Added the option
to the list of supported configurations.
No additional changes are needed as Turbopack already uses the
define-env config.
<!-- 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 #
-->
### What?
I noticed that code that was responsible for download the SWC Wasm
fallback wasn't bullet proof and there was a chance for a race
condition. The reason was that both `write` and `close` from a write
stream are async operations and it's best to wait for them to complete,
otherwise the promise returned from `body.pipeTo` could resolve before
all data has been written and the stream was closed. Right after that it
calls `rename` and it could happen that, at that point, `tempFile`
doesn't contain all the data yet which means an empty file may be
renamed into another file ending up with `path.join(cacheDirectory,
tarFileName)` being empty as well.
The fix is to wait for both `write` and `close` to be completed which
eliminates the potential race condition between the fetch and the
rename.
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
### What?
We are experimenting with `lightningcss`. This is about replacing
`swc_css` with `lightningcss` in turbopack, and the main reason for this
is to reduce the maintenance burden.
But when I tried, it introduced several regressions, so I'm putting it
behind an experimental flag.
You can enable `lightningcss` mode for **turbopack** by adding a flag to
the next config file.
```js
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: {
useLightningcss: true,
},
}
module.exports = nextConfig
```
Note that this is only for turbopack because we were not using `swc_css`
for non-turbopack mode of next.js
x-ref:
https://vercel.slack.com/archives/C03EWR7LGEN/p1700025496732229?thread_ts=1700019629.866549&cid=C03EWR7LGEN
### Why?
We should avoid regressions.
### How?
---
turbopack PR: https://github.com/vercel/turbo/pull/6456
Closes PACK-1966
---------
Co-authored-by: Leah <github.leah@hrmny.sh>
Refactors createComponentTree to return a top-level tree of all the
subtree data in the entire response. Although we were already collecting
this data, it's passed to the client as a prop LayoutRouter, which means
it can only be unwrapped by rendering the React tree.
Instead, we will hoist all the subtree data (i.e. the React nodes that
represent the nested layouts) into a top-level object that can be
immediately unwrapped by the client when it processes the response.
Then, the client will use this tree to eagerly populate the cache nodes,
rather than waiting for the LayoutRouter to lazily populate the cache
during render, like we do today.
This PR does not implement the client-side changes yet; it only creates
the new data structure, which I've named CacheNodeSeedData. The rest
will come in subsequent PRs.
---------
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This adds an additional item to the FlightData type. The type of the
field is currently `null`, but eventually this slot will represent a
tree of data that is used to seed the cache nodes.
This is a fragile change because the FlightData type is not covered by
TypeScript. This was an intentional decision to optimize the size of the
Flight payload. It's made more tricky because there are many places in
the codebase that access the fields of FlightData using direct indexing,
e.g. `flightData[0]`.
To minimze the number of places I needed to update, I added the new
field to the end of the array. However, many places access the fields
using negative indexing (via the `slice` method), so I needed to update
all of those. I also had to change any place that checked the length of
the array.
In the future, when we introduce clever types like this that are
intentionally unsound, we should contain the unsoundness to a single
module by only accessing the type with getter functions. Something like:
```js
const treePath = getTreePatch(flightData);
const seedData = getCacheNodeSeedData(flightData);
```
and so on.
That way when we add a new field like this, we don't have to carefully
update every single place that accesses the type. (TypeScript lacks the
ability to mark a type as opaque, unfortunately, but I believe you can
simulate it in other ways. This is one feature I miss from Flow.)
I considered adding these getter methods as part of this PR, but since
we're in the middle of a larger refactor of the Flight response type,
I'd prefer to change as little as possible for now until we can land an
MVP of PPR for client navigations. (That being said, if we struggle to
land this, I'll reconsider.)
My strategy for finding the places that needed to update was to change
the type of FlightDataPath to a nonsense type (e.g. number) and track
down all the TypeScript errors. I also searched for all references to
variables named `flightDataPath` or similar. I also referred to a prior
PR, #42791, which added the `head` field to the FlightDataPath type.
Because of the nature of the change, there's a moderately elevated risk
that this will break something. However, if something does slip through
the cracks, it's likely to fail fast, given how common most of these
paths are; I expect any egregious oversights would be caught by our e2e
test suite.
<!-- 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 #
-->
### What?
I changed the behavior of fetch() when 'force-dynamic' is specified in the `dynamic` of Route Segment Config to be similar to when 'force-no-store' is specified in `fetchCache`.
### Why?
The document (https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic) contains an explanation that when 'force-dynamic' is specified for `dynamic`, it will behave equivalently to the following:
> Setting the segment config to export const fetchCache = 'force-no-store'
I tried to correct it because it was not actually behaving this way.
### How?
When determining if `fetchCache` is 'force-no-store', I have modified the code to also check the `dynamic` setting.
Fixes#47033
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
### What?
When using the file system cache with `isrMemoryCacheSize: 0`, time-based revalidation is not working, and the file is constantly updated. I have also added some debug logging to mirror that in the `fetch-cache` handler
Detailed explanation in #58507
### Why?
The cached object's tags are incorrectly accessed, causing the cache to be rewritten every hit. This is catastrophic for a caching system that relies on file modification timestamps. The tags are one level up in the object from where [they are currently being accessed](9ab8828f72/packages/next/src/server/lib/incremental-cache/file-system-cache.ts (L178)).
Below shows a cached fetch representation on disk. When written, the tags reside at `obj.tags` instead of `obj.data.tags`
```json
{
"kind": "FETCH",
"data": {
"headers": {
"connection": "keep-alive",
"content-encoding": "br",
"content-type": "application/json; charset=utf-8",
"date": "Wed, 15 Nov 2023 21:17:42 GMT",
"server": "nginx/1.18.0 (Ubuntu)",
"transfer-encoding": "chunked",
"vary": "Accept-Encoding"
},
"body": "[SNIP]",
"status": 200,
"url": "https://timeapi.io/api/Time/current/zone?timeZone=UTC"
# this is where the current code is trying to pull the tags
# "tags": [ "time-with-fetch" ]
},
"revalidate": 20,
# tags actually live here
"tags": [
"time-with-fetch"
]
}
```
Fixes#58507
This PR makes sure that the `start-dev-server` trace span is recorded to the `.next/trace` file and uploaded to the telemetry endpoint when opted in.
Before this PR, the `start-dev-server` span was recorded in `next-dev` in the CLI. However, this would never be written to the `.next/trace` file since it happens in a different process (not the child process for next server). After this PR, the trace span happens in the next-server child process and will be recorded in the `.next/trace` file along with the other events produced by the dev server.
### What?
When using a `Request` object with fetch, we'll log a warning indicating that using the `cache` property in addition to `revalidate` is unsupported.
### Why?
`Request` sets some defaults on the request init, such as `cache: "default"`. This makes the warning confusing and there's no way to avoid it aside from switching the resource argument to be a URL string instead.
### How?
This keeps existing behavior but omits the log in the case where a request object is used and no explicit cache overrides are specified.
Fixes#58109
I'm working on a refactor to seed the CacheNodes as soon as the Flight
payload is received, rather than lazily during the render phase. This
means we no longer need to pass a child element prop to LayoutRouter via
childProp.
ChildProp includes two fields: a segment and a child element. The child
element is the part that will soon be removed, because we'll instead
always read from the cache nodes.
But even after this refactor, we still need to pass the segment to
LayoutRouter. So as an incremental step, I've inlined both fields into
separate props:
- childProp.current -> initialChildNode. This will be removed in a later
step in favor of reading from the cache nodes. In fact, we already
always read from the cache nodes — childProp is ignored completely once
the cache node is populated, hence the updated name.
- childProp.segment -> childPropSegment. This probably isn't the best
name anymore but I'll leave renaming until later once more of this
refactor has settled.
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: @BRKalow <bryce@clerk.dev>
### What?
A number of our customers have been experiencing issues stemming from an
`x-forwarded-host` header that doesn't match the `host` header.
### Why?
[This PR](https://github.com/vercel/next.js/pull/57815) removes
functionality which sets `x-forwarded-host` to `req.headers['host']` and
relies solely on the server's hostname and port.
This can be seen locally when visiting the app via a localhost
subdomain.
The `x-forwarded-host` header will remain as `localhost:${port}` while
the actual requested host will contain the subdomain.
### Related
- https://github.com/vercel/next.js/pull/57815#issuecomment-1808496790
---------
Co-authored-by: BRKalow <bryce@clerk.dev>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
### What?
When navigating between pages (via `prefetch: false`) within a dynamic
segment, the shared layout is re-rendered. This can cause unexpected
behavior like layout data changing when navigating between child
segments.
### Why?
When prefetch is false, we're currently opting into an "optimistic
navigation" codepath, which will optimistically render layout-routers up
to the point where data is missing, while kicking off data fetches. It
attempts to determine where refetching needs to happen by traversing the
router cache nodes and checking where data is missing. However, it
locates these cache nodes by using "segments" obtained by
[deconstructing the
URL](https://github.com/vercel/next.js/blob/fix/optimistic-bailout/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts#L142),
which won't accurately contain dynamic segment data. For ex, `/en` which
corresponds with `/app/[lang]/page.tsx` will have a cache node key of
`lang|en|d`, not `en`. Similarly, the optimistic tree that gets
constructed will also be incorrect, since it uses the URL segment.
### How?
My initial fix was to match the dynamic segment against the segment
constructed by the URL. But after discussion with @sebmarkbage and the
team, it seems more correct to remove the optimistic case all together
as there's no guarantee that the url will actually match to that
segment.
Fixes#50670
---------
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
### What?
Using `revalidateTag` or `revalidatePath` in a route handler will not
currently opt the handler into dynamic behavior. This means that if you
use these APIs and don't opt into dynamic behavior by some other means,
the revalidation call won't do anything as the route handler will be
served statically.
### Why?
During static generation, we do not currently indicate that usage of
these APIs should opt into dynamic usage.
### How?
This updates `revalidateTag` to throw a `DynamicUsageError` (similar to
our other scenarios, such as search params bailout, headers/cookies, or
fetch + revalidate/no-store)
Closes NEXT-1712
This serves to address a few problems as it relates to headers handling within the App Page render pipeline.
1. During static generation, we should not write to the response directly as the revalidation for static responses is performed out of band from the actual request/response as a stale version can be served early. This is partially addressed by modifying the `onHeaders` to only write when there it is not during static generation, but long term I'd hope to see that we can instead pass a immutable request and `null` for the response to help indicate to the render pipeline that it should instead persist the data into the `RenderResult` objects. Alternatively, the response could use a mocked version that would then supersede the `RenderResult` and be used instead.
2. The types for rendering App Pages were merged incorrectly, so this additionally restructures the way that we initialize those renderers such that only the options that are applicable to each renderer is passed down.
Requires vercel/turbo#6388
This uses the structure implemented in vercel/turbo#6388 to support formatted text when reporting. Right now only the `Line` and basic `String` cases are handled.
### What?
This stops Turbopack from erroring out when trying to parse apps using NextConfig's legacy `experimental.serverActions` boolean value.
### Why?
Old apps may not have removed the legacy boolean flag, but should still run.
### How?
At first I attempted updating Zod's configuration to use a default option config when a boolean was encountered, and passing the updated config to Turbopack, but this would hide the warning message. Then I tried implementing a custom `Deserializer` on the Rust side to handle boolean values and default. But, it was just so much easier to implement with a enum supporting both the current and the legacy configuration.
Closes PACK-1962
### What?
When `FetchCache` is used, cache gets were incorrectly bailing. This would result in unexpected behavior, like continuously revalidating a cache key, as described in #57978.
### Why?
#57902 introduced a refactor to the `FileSystemCache` and changed the interface of `get`, but this change was not propagated to `FetchCache`. Specifically, `fetchCache` was removed in favor of a new type `kindHint`. As a result, cache reads would always short circuit because `fetchCache` would never be defined.
### How?
This updates the interface on `FetchCache` to match what is defined on the base `CacheHandler`. I've also updated the args to both `get` and `set` to be derived from `CacheHandler` so we don't have any type inconsistencies in the future.
I will be following up with a test in the CLI repo to test against a deployed app (since minimalMode cannot be easily mocked in our test suite). Manually verified these changes against the repro in the original issue below, at the following URLs:
https://revalidate-vercel-test-iota.vercel.app/fetch-cache-testhttps://revalidate-vercel-test-iota.vercel.app/revalidate-tag-testFixes#57978Fixes#58306
Previously, the incremental cache returned objects with a readable stream (that were consumed). These can't be shared. Instead, this modifies the cache to instead return strings which are sharable.
This also fixes a bug related to revalidation when writing an updated prefetch RSC payload to the filesystem when PPR is enabled. Previously it just wrote to `.rsc` and now it correctly writes a `.prefetch.rsc` file instead.
## Description
Between 14.0.2-canary.6 and 14.0.2-canary.7, a change was introduced in vercel/next.js#56497 that turned the Redux store state into a Promise, rather than a synchronous state update.
This caused the `sync` function -- used to send state updates to the Redux Devtools -- to be recreated on every dispatch, which in turn, by referential instability, caused the `HistoryUpdater` component to re-render and trigger a `history.replaceState` with no particular change, but with the internal `canonicalUrl`.
When an app does a soft/shallow navigation by calling history methods directly (currently the only way to do shallow search params updates in the app router), these changes would have been overwritten by any prefetch (eg: hovering or mounting a Link), which is usually a no-op for the navigation state.
This PR changes the `sync` function to take the state as an argument rather than as a closure. The whole app router state is also unwrapped only once, and fed to the HistoryUpdater. Changes to its contents made by reducers will cause the HistoryUpdater effect to re-run, triggering history updates and a call to the sync function.
## Context
I maintain [`next-usequerystate`](https://github.com/47ng/next-usequerystate), which is used in the Vercel dashboard, and which is impacted by this change (see
[#388](https://github.com/47ng/next-usequerystate/issues/388)).
## History
@timneutkens introduced the `sync` function and the whole Redux devtools reducer in vercel/next.js#39866, with the note:
> a new hook useReducerWithReduxDevtools has been added, we'll probably want to put this behind a compile-time flag when the new router is marked stable but until then it's useful to have it enabled by default (only
when you have Redux Devtools installed ofcourse).
If a different direction is needed to keep sending `RENDER_SYNC` actions to Redux devtools, I'll be happy to rework this PR to move the `sync` function into the action queue.
## Changes
- [x] Added e2e test. Requires a `start` mode as prefetch links are disabled in development. Test was verified to fail from next@>=12.0.2-canary.7 without the fix.
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
<!-- 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?
-->
This PR fixes a bug where the expected catch-all route would not match
if there were multiple "catch-all routes" under the "parallel route”.
The page on the non-parallel routes path matches the catch all routes.
that exist on the more detailed path.
However, under parallel routes, it matches the most parent page of all
the pages with catch all routes.
For example, if there are files like below:
```
app/@sidebar/[...catchall]/page.tsx
app/@sidebar/dashboard/[...catchall]/page.tsx
```
When accessing `/foo`, it should match
`app/@sidebar/[...catchall]/page.tsx`, and this is working correctly.
However, when accessing `/dashboard/foo`, it should match
`app/@sidebar/dashboard/[...catchall]/page.tsx`, but
`app/@sidebar/[...catchall]/page.tsx` is being matched instead.
## Repository to reproduce
https://github.com/nonoakij/fix-parallel-routes-with-catch-all
## Related PR
https://github.com/vercel/next.js/pull/58215
---------
Co-authored-by: Jimmy Lai <laijimmy0@gmail.com>
## What?
This PR introduces support for manually calling `history.pushState` and `history.replaceState`.
It's currently under an experimental flag:
```js
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: {
windowHistorySupport: true,
},
}
module.exports = nextConfig
```
Going forward I'll refer to `history.pushState` as `replaceState` is interchangable.
When the flag is enabled you're able to call the web platform `history.pushState` in the usual way:
```js
const data = {
foo: 'bar'
}
const url = '/my-new-url?search=tim'
window.history.pushState(data, '', url)
```
Let's start by explaining what would happen without the flag:
When a new history entry is pushed outside of the Next.js router any back navigation to that history entry will cause a browser reload as it can no longer be used by Next.js as the required metadata for the router is missing. In practice this makes it so that pushState/replaceState is not feasible to be used. Any pathname / searchParams added can't be observed by `usePathname` / `useSearchParams` either.
With the flag enabled the pushState/replaceState calls are instrumented and is synced into the Next.js router. This way the Next.js router's internal metadata is preserved, making back navigations apply still, and pathname / searchParams is synced as well, making sure that you can observe it using `usePathname` and `useSearchParams`.
## How?
- Added a new experimental flag `windowHistorySupport`
- Instruments `history.pushState` and `history.replaceState`
- Triggers the same action as popstate (ACTION_RESTORE) to sync the provided url (if provided) into the Next.js router
- Copies the Next.js values kept in history.state so that they are not lost
- Calls the original pushState/replaceState
~~Something to figure out is how we handle additional pushes/replaces in Next.js as that should override the history state that was previously set.~~
Went with this after discussing with @sebmarkbage:
- When you open a page it preserves the custom history state
- This is to solve this case: when you manually `window.history.pushState` / `window.history.replaceState` and then do an mpa navigation (i.e. `<a>` or `window.location.href`) and the navigate backwards the custom history state is preserved
- When you navigate back and forward (popstate) it preserves the custom history state
- When you navigate client-side (i.e. `router.push()` / `<Link>`) the custom history state is not preserved
Currently, when a webpack compilation warning is processed by
`WellKnownErrorsPlugin` and it's indeed a well know error that should be
bypassed, the warning item is simply deleted from the array, which will
produce an array with empty items:
Example:
```js
{
client: {
loading: false,
totalModulesCount: 2172,
errors: null,
warnings: [ <1 empty item> ]
},
server: {
loading: false,
totalModulesCount: 2119,
errors: null,
warnings: [ <1 empty item> ]
},
edgeServer: {
loading: false,
totalModulesCount: 58,
errors: null,
warnings: null
},
trigger: undefined,
amp: {}
}
```
This array with empty items generates a side effect on the [build
output](3553c6516d/packages/next/src/build/output/store.ts (L124)),
since the `warning` array has empty items:
```
➤ npm run dev
> next dev
▲ Next.js 14.0.1-canary.3
- Local: http://localhost:3000
- Environments: .env.development
✓ Ready in 2.6s
✓ Compiled /middleware in 109ms (58 modules)
○ Compiling /(dashboard)/page ...
⚠
⚠
```
![CleanShot 2023-10-30 at 13 20
42@2x](https://github.com/vercel/next.js/assets/33168/fd25bc72-61d6-4446-83cb-87768d5135dd)
This PR solves this issue by removing the `warning` item using the
`Array.prototype.splice`, which removes the item instead of making the
array position empty.
Related PR: https://github.com/vercel/next.js/pull/57073
---------
Co-authored-by: Jimmy Lai <laijimmy0@gmail.com>