In fact, this is an issue that has been solved in #52033, but it seems
#52492 introduced it again.
> During development, for fonts created via next/font the file path is
already containing the hash so we can always have them cached. This
fixes the problem of fonts causing FOUC in HMR.
Fixes#50782
---------
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
This commit updates some of the code organization in app-render in
preparation for supporting dynamic RSC repsonses on top of static SSR
responses for PPR. The main change to notice is the separation of
creating the server component renderer which initiates the RSC render
and executes in the RSC layer with the consuming component which lives
in the SSR layer. By organizing the code this way we can later only call
the server render in certain cases, omitting the SSR render entirely.
This is different than just using the generaetFlight pathway because
that pathway serves client navs and does not actually render the same
output that the intial render does.
Closes NEXT-1889
Previously in #58967 we set all the module type as `'es6'` to let swc
parse app router code as ESM and output as ESM due to the incorrect
detection of CJS module by auto-cjs plugin, but this is not accurate
when the external library bundle is CJS. The problem is when swc
compiling modern syntax for example private properties in CJS bundle but
emitted the swc helpers with ESM imports.
We had a auto-cjs swc plugin to determine if the file is using CJS or
not, @kdy1 fixed the bug of it so now we can use the default module
type, and let the plugin to determine its module type, to make sure
we're emitting the right helpers.
Closes NEXT-1942
Based on #60118
Use dynamic import instead of require to load the incremental cache
handled, so when using ESM it will still work.
Updated the tests and merged them into new test suite, include 3 cases
of custom cache definition:
- CJS with `module.exports`
- CJS with `exports.default` with ESM mark
- ESM with `export default`
Closes NEXT-1924
Fixes#58509
The start line of build logging `Creating an optimized production build
...` was logged by spinner, and when all build is finished we stop that
spinner. But the problem is all the logs from a page such as warnings
will be also leaded by it since they interrupted the spinner.
We changed the spinner to a one-line log now that will make the warning
logs more clear and let the page-level build logs print without messed
with app-level build logs.
#### After
```
▲ Next.js 14.0.5-canary.34
Creating an optimized production build ...
⚠ Next.js can't recognize the exported `runtime` field in "/Users/huozhi/workspace/next.js/test/e2e/app-dir/app-edge/app/expo
rt/inherit/page.tsx" as it was not assigned to a string literal.
The default runtime will be used instead.
⚠ Next.js can't recognize the exported `preferredRegion` field in "/Users/huozhi/workspace/next.js/test/e2e/app-dir/app-edge/
app/export/inherit/page.tsx" as it was not assigned to a string literal or an array of string literals.
The default runtime will be used instead.
```
#### Before
```
▲ Next.js 14.0.5-canary.34
Creating an optimized production build ... ⚠ Next.js can't recognize the exported `runtime` field in "/Users/huozhi/worksp
ace/next.js/test/e2e/app-dir/app-edge/app/export/inherit/page.tsx" as it was not assigned to a string literal.
The default runtime will be used instead.
⚠ Next.js can't recognize the exported `preferredRegion` field in "/Users/huozhi/workspace/next.js/test/e2e/app-dir/app-edge/
app/export/inherit/page.tsx" as it was not assigned to a string literal or an array of string literals.
The default runtime will be used instead.
Creating an optimized production build ... ⚠ Next.js can't recognize the exported `runtime` field in "/Users/huozhi/worksp
ace/next.js/test/e2e/app-dir/app-edge/app/export/inherit/page.tsx" as it was not assigned to a string literal.
The default runtime will be used instead.
⚠ Next.js can't recognize the exported `preferredRegion` field in "/Users/huozhi/workspace/next.js/test/e2e/app-dir/app-edge/
app/export/inherit/page.tsx" as it was not assigned to a string literal or an array of string literals.
The default runtime will be used instead.
```
Closes NEXT-1939
Closes NEXT-1947
### What?
Next.js throws a hard `SEGMENT MISMATCH` error when the reducers were
unable to apply the a patch to the router tree from the server response.
### How?
Rather than crashing the router, this will treat segment mismatches as a
MPA navigation, to restore the client router into a working state.
### Test Plan
If there are specific scenarios where Next.js throws this error, it
should most likely be fixed in Next and not in user-land. Since it's not
currently obvious what scenarios will trigger this error, this PR serves
to recover from a mismatch more gracefully and provides some debug
information rather than crashing the application. As such, there's no
easy way to create an E2E test for this and I've instead opted for a
simple unit test.
Closes NEXT-1878
[slack
x-ref](https://vercel.slack.com/archives/C017QMYC5FB/p1704214439768469)
[slack
x-ref](https://vercel.slack.com/archives/C03KAR5DCKC/p1702565978694519)
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
## What?
Always call `createPagesMapping` as it already handles the case when
there are no paths.
Also introduces `PAGE_TYPES` to have a single source of truth for these
types and where they're used. As you can see this replaces a ton of
hardcoded `'app'`, `'pages'`, and `'root'` references.
<!-- 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 #
-->
Closes NEXT-1935
## What?
While working on some other refactors I noticed that this check for
duplicate routes is incorrect.
Upon further investigation with @feedthejim we noticed that this check
can be removed altogether as it's already being checked correctly in the
route matcher.
I've moved the test to use `createNextDescribe` and removed the check
for build because it's a dev-only warning.
<!-- 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 #
-->
Closes NEXT-1941
## What?
While looking at other refactors I noticed that `entrypoint.name ===
'root'` was checked which is surprising as `root` is not any of the
injected entrypoints.
Also noticed that there's a `root` parameter that refers to the very
first name of App Router, which was the `root` directory instead of
`app` directory. That variable could be removed as it's in scope above.
<!-- 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 #
-->
Closes NEXT-1938
## What?
While looking into some refactors for `next build` I noticed that
`NextBuildContext` was used to propagate if instrumentation.js exists or
not, however that information can be inferred by checking if the
entrypoint exists in the compiler. Applied that change.
I've updated the test fixtures to include the `next.config.js` so that
you can run them using `pnpm next`.
<!-- 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 #
-->
Closes NEXT-1931
## What
When users specify `"type": "module"` in Next.js app, especially with
`create-next-app`, `Image` component is not working. An error
`Unsupported Server Component type: {...}` is thrown.
## Why
`next/image` API is mixing with a client component as default export and
a named export as server component. But the entry file of the API is
still CJS file, which will import the module as the object. So you'll
get `{ default, unstable_getImageProps }` when you do `import Image from
'next/image'` instead of `Image` component itself, where the CJS module
load all the exports as an object. This is expected behavior for ESM but
breaks the usage.
It only errors when you're using js extensions, if you're using
typescript, it still works. If you're using turbopack, it works in dev
mode.
This is also because webpack can't analyze the exports from CJS module
of that `next/image` entry file. Usually we can assign the default
export to the module itself, then attach other named exports onto it, so
the default export equals the `module.exports` itself. But for
`next/image` since the default export is an client component, doing that
will error with React as you cannot modify the react client reference.
Turbopack doesn't use the same way to analyze the default export, so it
doesn't have this problem.
## How
We create few ESM version of entry files of nextjs APIs, then pick up
them to let app router for bundling, instead of using the `next/<api
name>.js` CJS files. Those ESM entries still point to the `next/dist/..`
CJS files. In this way webpack and directly gets the exports from the
`next/dist/...` files and be aware of the module exports. No more CJS
module wrapping the ESM module, the default and named exports can
preserve correctly.
Fixes#54777
Closes NEXT-1774
Closes NEXT-1879
Closes NEXT-1923
### What?
When handling route interception in two different segments but handled
by the same interception route, the first interception will show the
correct component but attempting the same interception on another
segment will return elements from the first request, not the second.
### Why?
Prefetch cache entries are created from the browser URL. However, route
interception makes use of `nextUrl` to mask the underlying components
that are being fetched from the server to handle the request
Consider the following scenario:
```
app
foo
@modal
(...)post
[id]
bar
@modal
(...post)
[id]
post
[id]
```
If you trigger an interception on `/foo`, your URL is going to be masked
to `/post/1` and keyed as such in the prefetch cache. However, the cache
entry is actually associated with `app/foo/@modal/(...post)/[id]`. That
means when you trigger the same interception on `/bar`, it will return
the tree from `/foo`.
### How?
This PR will prefix the prefetch cache key with `state.nextUrl` when
necessary.
Fixes#49878Fixes#52748
Closes NEXT-1818
### What?
Catch-all routes are being matched to parallel routes which causes
issues like an interception route being handled by the wrong page
component, or a page component being associated with multiple pages
resulting in a "You cannot have two parallel pages that resolve to the
same path" build error.
### Why?
#58215 fixed a bug that caused catchall paths to not properly match when
used with parallel routes. In other words, a catchall slot wouldn't
render on a page that could match that catch all. Or a catchall page
wouldn't match a slot. At build time, a normalization step was
introduced to take application paths and attempt to perform this
matching behavior.
However in it's current form, this causes the errors mentioned above to
manifest. To better illustrate the problem, here are a few examples:
Given:
```
{
'/': [ '/page' ],
'/[...slug]': [ '/[...slug]/page' ],
'/items/[...ids]': [ '/items/[...ids]/page' ],
'/(.)items/[...ids]': [ '/@modal/(.)items/[...ids]/page' ]
}
```
The normalization logic would produce:
```
{
'/': [ '/page' ],
'/[...slug]': [ '/[...slug]/page' ],
'/items/[...ids]': [ '/items/[...ids]/page' ],
'/(.)items/[...ids]': [ '/@modal/(.)items/[...ids]/page', '/[...slug]/page' ]
}
```
The interception route will now be improperly handled by
`[...slug]/page` rather than the interception handler.
Another example, which rather than incorrectly handling a match, will
produce a build error:
Given:
```
{
'/': [ '/(group-b)/page' ],
'/[...catcher]': [ '/(group-a)/@parallel/[...catcher]/page' ]
}
```
The normalization logic would produce:
```
{
'/': [ '/(group-b)/page', '/(group-a)/@parallel/[...catcher]/page' ],
'/[...catcher]': [ '/(group-a)/@parallel/[...catcher]/page' ]
}
```
The parallel catch-all slot is now part of `/`. This means when building
the loader tree, two `children` parallel segments (aka page components)
will be found when hitting `/`, which is an error.
The error that was added here was originally intended to help catch
scenarios like:
`/app/(group-a)/page` and `/app/(group-b)/page`. However it also throws
for parallel slots, which isn't necessarily an error (especially since
the normalization logic will push potential matches).
### How?
There are two small fixes in this PR, the rest are an abundance of e2e
tests to help prevent regressions.
- When normalizing catch-all routes, we will not attempt to push any
page entrypoints for interception routes. These should already have all
the information they need in `appPaths`.
- Before throwing the error about duplicate page segments in
`next-app-loader`, we check to see if it's because we already matched a
page component but we also detected a parallel slot that would have
matched the page slot. In this case, we don't error, since the app can
recover from this.
- Loading a client reference manifest shouldn't throw a cryptic require
error. `loadClientReferenceManifest` is already potentially returning
undefined, so this case should already be handled gracefully
Separately, we'll need to follow-up on the Turbopack side to:
- Make sure the duplicate matching matches the Webpack implementation (I
believe Webpack is sorting, but Turbopack isn't)
- Implement #58215 in Turbopack. Once this is done, we should expect the
tests added in this PR to start failing.
Fixes#58272Fixes#58660Fixes#58312Fixes#59782Fixes#59784
Closes NEXT-1809
Adds a regression test and a fix for a bug that sometimes happens when a
prefetched route on the client becomes stale — the app would get stuck
in a loading state.
The problem was the condition I used to fallback to the non-PPR
implementation, inside navigateReducer. It was too narrow, causing
prefetched segments that contained dynamic holes to sometimes be treated
as if they were complete. The net effect was that the dynamic data would
never stream in, and the page would get stuck in a fallback state until
the stale prefetch was eventually purged from the cache, or the user
refreshed the page.
The reason the mistake happened was, as an incremental step, I decided
to fallback to the non-PPR implementation for any case where I hadn't
yet implemented the equivalent functionality. I think still think this
is a good strategy, despite the mistake, but I'm eager to get everything
migrated to the new model as soon as possible.
Closes NEXT-1920
We already have variables of swc loaders for different bundling layers,
the composed one should just be loaders instead of being called "swc
loader"
Closes NEXT-1917
If a user accidentally configures a non-valid `revalidate` value this
ensures we show a proper error message instead of silently tolerating
it.
Closes: NEXT-1896
Closes NEXT-1915
For a more detailed explanation of the algorithm, refer to the comments
in ppr-navigations.ts. Below is a high-level overview.
### Step 1: Render the prefetched data immediately
Immediately upon navigation, we construct a new Cache Node tree (i.e.
copy-on-write) that represents the optimistic result of a navigation,
using both the current Cache Node tree and data that was prefetched
prior to navigation.
At this point, we haven't yet received the navigation response from the
server. It could send back something completely different from the tree
that was prefetched — due to rewrites, default routes, parallel routes,
etc.
But in most cases, it will return the same tree that we prefetched, just
with the dynamic holes filled in. So we optimistically assume this will
happen, and accept that the real result could be arbitrarily different.
We'll reuse anything that was already in the previous tree, since that's
what the server does.
New segments (ones that don't appear in the old tree) are assigned an
unresolved promise. The data for these promises will be fulfilled later,
when the navigation response is received.
The tree can be rendered immediately after it is created. Any new trees
that do not have prefetch data will suspend during rendering, until the
dynamic data streams in.
### Step 2: Fill in the dynamic data as it streams in
When the dynamic data is received from the server, we can start filling
in the unresolved promises in the tree. All the pending promises that
were spawned by the navigation will be resolved, either with dynamic
data from the server, or `null` to indicate that the data is missing.
A `null` value will trigger a lazy fetch during render, which will then
patch up the tree using the same mechanism as the non-PPR implementation
(serverPatchReducer).
Usually, the server will respond with exactly the subset of data that
we're waiting for — everything below the nearest shared layout. But
technically, the server can return anything it wants.
This does _not_ create a new tree; it modifies the existing one in
place. Which means it must follow the Suspense rules of cache safety.
## To Do
Not all necessarily PR-blocking, since the status quo is that
navigations don't work at all when PPR is enabled
- [x] Figure out how to handle dynamic metadata. Need to switch from
prefetched metadata to final.
- [x] Some mistake related to parallel routes, need to look into failing
tests
Closes NEXT-1894
### What?
Navigating to a layout that is part of a route group that uses route
interception currently will trigger a 404 error if the route group
doesn't define a `default` segment.
### Why?
When `next-app-loader` injects fallback defaults into the loader tree,
it does so by first seeing if a default already exists. However it does
this without ignoring route groups, meaning if you have a
`/app/default.tsx` and your interception route is at
`/app/(level1)/(level2)`, it will look for the default at
`/app/(level1)/(level2)/default.tsx`.
When a `default` isn't found, the fallback behavior is to trigger a
`notFound()` error. This means navigating to the intercepting route that
has no `default` for the `children` segment will 404.
### How?
This adjusts the fallback behavior by attempting to find the `default`
by normalizing the segment path, which will ignore route groups. That
way `/app/(level1)/(level2)/default` will first check `/app/default.tsx`
before falling back to `notFound` behavior.
Fixes#59279
Closes NEXT-1813
If the data for a segment is missing when LayoutRouter renders, it
initiates a lazy fetch to patch the cache. This is how all dynamic data
fetching works in the pre-PPR implementation.
For PPR, we won't use this mechanism anymore for regular navigations,
but (at least for now) we will still use it as a fallback behavior if
the server response does not match what we expected to receive.
This commit adds support for asynchronously triggering a lazy fetch, by
unwrapping the segment data promise inside LayoutRouter to check if it's
missing. If so, it will trigger the lazy fetch mechanism.
When PPR is not enabled this should not observably impact behavior.
Closes NEXT-1893
When uploading traces from `.next/trace`, target paths that trigger
compilations were being normalized to paths like
`[project]/../../../../../middleware`. This PR removes the normalization
logic so that the triggers appear as `/middleware` which is easier to
understand.
## What?
Moves the changeSubscription for _document into the finally block,
similar to how the page itself is handled there as well.
This should allow moving the rest of the try block into a separate
function that can be reused for builds too.
<!-- 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 #
-->
Closes NEXT-1885
## What?
I'm working on consolidating a bunch of the file writing related pieces
in the Turbopack handling in the dev server so that it can be abstracted
out as it's needed for `next build` too.
These changes make sure that there is a single `writeManifests()`
instead of picking specific manifests to write.
We can optimize this later but for now the overhead of writing them to
disk separately is negligible.
<!-- 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 #
-->
Closes NEXT-1884
### What?
There are a bunch of different bugs caused by the same underlying issue,
but the common thread is that performing any sort of router cache update
(either through `router.refresh()`, `revalidatePath()`, or `redirect()`)
inside of a parallel route would break the router preventing subsequent
actions, and not resolve any pending state such as from `useFormState`.
### Why?
`applyPatch` is responsible for taking an update response from the
server and merging it into the client router cache. However, there's
specific bailout logic to skip over applying the patch to a
`__DEFAULT__` segment (which corresponds with a `default.tsx` page).
When the router detects a cache node that is expected to be rendered on
the page but contains no data, the router will trigger a lazy fetch to
retrieve the data that's expected to be there
([ref](5adacb6912/packages/next/src/client/components/layout-router.tsx (L359-L370)))
and then update the router cache once the data resolves
([ref](5adacb6912/packages/next/src/client/components/layout-router.tsx (L399-L404))).
This is causing the router to get stuck in a loop: it'll fetch the data
for the cache node, send the data to the router reducer to merge it into
the existing cache nodes, skip merging that data in for `__DEFAULT__`
segments, and repeat.
### How?
We currently assign `__DEFAULT__` to have `notFound()` behavior when
there isn't a `default.tsx` component for a particular segment. This
makes it so that when loading a page that renders a slot without slot
content / a `default`, it 404s. But when performing a client-side
navigation, the intended behavior is different: we keep whatever was in
the `default` slots place, until the user refreshes the page, which
would then 404.
However, this logic is incorrect when triggering any of the above
mentioned cache node revalidation strategies: if we always skip applying
to the `__DEFAULT__` segment, slots will never properly handle reducer
actions that rely on making changes to their cache nodes.
This splits these different `applyPatch` functions: one that will apply
to the full tree, and another that'll apply to everything except the
default segments with the existing bailout condition.
Fixes#54173Fixes#58772Fixes#54723Fixes#57665
Closes NEXT-1706
Closes NEXT-1815
Closes NEXT-1812
## What?
Ensures `Object.entries` is not called on the `Map`. Seems this only
fails in a very particular case but potentially this fixes other issues
than the one I added in the tests too.
## How?
`Object.entries()` results in an empty array when called on a `Map`.
Created a shared type declaration for the value and removed the
`Object.entries`. Benefit of this is that we can skip the loop as well.
<!-- 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?
Small refactor to move Turbopack hotreloader interface creation to a
separate function: `createHotReloaderTurbopack`.
Renamed `HotReloader` to `HotReloaderWebpack`.
Initially wanted to move `createHotReloaderTurbopack` to a separate file
but it relies on a bunch of in-scope variables so that is not
straightforward. Will do that later.
<!-- 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 #
-->
Closes NEXT-1881
This fixes some of headers (and adds associated tests) for pages when
PPR is enabled. Namely, the `Cache-Control` headers are now returning
correctly, reflecting the non-cachability of some requests:
- Requests that postpone (dynamic data is streamed after the initial
static shell is streamed)
- Requests for the Dynamic RSC payload
Additionally, the `X-NextJS-Cache` header has been updated for better
support for PPR:
- Requests that postpone no longer return this header as it doesn't
reflect the cache state of the request (because it streams)
- Requests for the Prefetch RSC now returns the correct cache headers
depending on the segment and pre-postpone state
This also enables the other pathnames in the test suites 🙌🏻
Closes NEXT-1840
When PPR is enabled, the CacheNodeSeedData and FlightRouterState
contained in an RSC payload (whether it's static or dynamic) should
always have the same tree structure.
The only reason the two trees would ever be different is if the server
partially renders with `loading.tsx`, but that behavior doesn't exist
when PPR is enabled. (In that case, the CacheNodeSeedData would describe
only a subset of FlightRouterState.)
The behavior is already correct but to make the types a bit closer, this
changes the `parallelRoutes` slot of CacheNodeSeedData to be
non-nullable; if there are no children, it should be an empty object.
It's not semantically important, I'm only changing it to make the types
more consistent, since we typically traverse both trees in parallel.
Eventually we will probably merge these into a single transport type.
Closes NEXT-1868
The PPR implementation of navigateReducer is expected to diverge
significantly from the existing, non-PPR implementation. So this forks
them into two separate functions. This will be easier to maintain than
two different implementations inside the same function, especially
considering we don't expect any more changes to the non-PPR
implementation.
This also reduces the chances we'll introduce an accidental regression
into the non-PPR version, which is the stable one that all users (except
for the ones dogfooding PPR) are currently using.
For now, the two implementations are identical. I'll start making
changes in subsequent PRs.
Only one implementation will be included in the final build; the other
one will be dead code eliminated because the feature check is statically
inlined at build time:
```js
export const navigateReducer = process.env.__NEXT_PPR
? navigateReducer_PPR
: navigateReducer_noPPR
```
Closes NEXT-1856
This ensures that `export const dynamic = 'force-static'` is properly
honored when a page contains fetches with `cache: 'no-store'`, `cache:
'no-cache'` or `next: { revalidate: 0 }`.
Closes NEXT-1858
Implementation of feature request opened here -
https://github.com/vercel/next.js/discussions/59427
Approach:
~~We are using micromatch in the csrf protection step of actionHandler
to allow for wildcard domains passed in allowedDomains. This is the same
library used for matching domains for remote images.~~
If any of the allowed domains match the origin of the request, we skip
the downstream error thrown for csrf protection.
Edit:
Micromatch is not available in this context as it is only compatible
with Node. This codepath can be run from the edge, so we need to rely on
vanilla js compatible code only.
Instead of falling back to allowing the user to pass in a regex, which
can be somewhat insecure, we opt into continuing to use a wildcard
pattern from a configuration standpoint and instead use a simple
function that matches on wildcards using string comparison and
iteration.
Ideally, Micromatch can be retrofitted to work in non-Node settings and
this piece of code can be replaced in the future, without deprecating or
changing the next.config interface.
---------
Co-authored-by: Josh Story <story@hey.com>
Adds a new field `prefetchRsc` to CacheNode that will be used by the PPR
implementation. It represents a static version of the segment that can
be showed immediately, and may or may not contain dynamic holes. It's
prefetched before a navigation occurs. During rendering, we will choose
whether to render `rsc` or `prefetchRsc` with `useDeferredValue`.
As with the `rsc` field, a value of `null` means no value was provided.
In this case, the LayoutRouter will go straight to rendering the `rsc`
value; if that one is also missing, it will suspend and trigger a lazy
fetch.
The non-PPR implementation will never set this value.
This PR adds the field to the CacheNode type but doesn't implement any
of the behavior yet. Mostly this involves updating the router reducer
unit tests.
Closes NEXT-1855
Passing `NODE_OPTIONS='--inspect'` was failing because a sub-process was
getting created (`getRegistry()`) which would trigger a "address already
in use" error when the process inherited the same debugger port from the
parent process.
I had to disable this test in
https://github.com/vercel/next.js/pull/59508 because it wasn't passing,
CI was just skipping it. This PR fixes the behavior and re-enables the
test.
Fixes#55862
Closes NEXT-1854
I want to give this field a name that's bit less generic and
distinguishes it from `lazyData` (because that one has a different type
and is a special case we want to eventually remove).
I'm also about to add an optional `prefetchRsc` field that represents a
prefetched version of the same value. The common suffix is meant to
communicate how they are related.
Doing this rename in its own PR because it's a pure find-and-replace,
whereas the later steps are not.
Closes NEXT-1846
This updates the `collectGenerateParams` method to use a loop rather
than being recursive as well as updating some of the Typescript types.
This is a follow up of #59420.
Closes NEXT-1839
`CacheNode.data` is used to lazily kick off a request during render, and
represents the result of the entire Flight response. It doesn't
correspond directly to the RSC data of the cache node itself — that's
`subTreeData`. To complicate things further, I'm about to add another
field to CacheNode that represents prefetched RSC data.
To make it a little less confusing, I've renamed the `data` field to
`lazyData`. Still not perfectly clear on first glance, but it's at least
more specific. With PPR, the goal is to remove the lazy data fetching
mechanism in favor of initiating the request immediately upon
navigation. So this field will eventually go away.
In the next PR, I will rename `subTreeData`, too. Perhaps something with
"rsc" in the name so it's less generic than "data".
Closes NEXT-1843
I'm about to make some changes to the CacheNode data structure, and
before I add more complexity, I noticed an opportunity to remove some —
the `status` field isn't logically necessary:
- The `DATA_FETCH` and `LAZY_INITIALIZED` states are already treated as
equivalent; in either case, they will cause the render to suspend during
render, trigger a lazy data fetch (if one hasn't been triggered
already), and then update the router with the result of the response.
- `subTreeData` is null if and only if the node is in the `DATA_FETCH`
or `LAZY_INITIALIZED` states, and it always causes the render to
suspend. So rather than check if the status is one of those, we can
check if `subTreeData` is null.
The most important changes are to CacheNode type in
app-router-context.shared-runtime and the lazy fetching logic in
LayoutRouter. Everything else in the diff is related to deleting the
`status` field wherever a CacheNode is referenced, like in the reducer
unit tests.
Closes NEXT-1842
Before PPR, the way instant navigations work in Next.js is we prefetch
everything up to the first route segment that defines a loading.js
boundary. The rest of the tree is defered until the actual navigation.
It does not take into account whether the data is dynamic — even if the
tree is completely static, it will still defer everything inside the
loading boundary.
The approach with PPR is different — we prefetch as deeply as possible,
and only defer when dynamic data is accessed. If so, we only defer the
nearest parent Suspense boundary of the dynamic data access, regardless
of whether the boundary is defined by loading.js or a normal <Suspense>
component in userspace.
This PR removes the partial behavior of loading.js when the PPR flag is
enabled. In effect, loading.js now acts like a regular Suspense boundary
with no additional special behavior.
Note that in practice this usually means we'll end up prefetching more
than we were before PPR, which may or may not be considered a
performance regression by some apps. The plan is to address this before
General Availability of PPR by introducing granular per-segment
fetching, so we can reuse as much of the tree as possible during both
prefetches and dynamic navigations. But during the beta period, we
should be clear about this trade off in our communications.
## Testing strategy
While I was writing a test, I noticed that it's currently pretty
difficult to test all the scenarios that PPR is designed to handle, so I
gave special attention to setting up a testing strategy that I hope will
make this easier going forward. The overall pattern is based on how
we've been testing concurrent rendering features in the React repo for
many years:
- In the e2e test, spin up an HTTP server for responding to requests
sent by the test app. This simulates the data service that would be used
in a real Next.js application, whether it's direct db access, an ORM, or
a higher-level data access layer. The e2e test can observe when
individual requests are received, and control the timing of when the
data is fulfilled, without needing to mock any lower level I/O. (We're
already using a similar pattern to [test fetch
deduping](a3616d33ed/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts (L8-L29)).)
- Each time a request is received, write to an event log. Then assert on
the result of the log at different points throughout the test. This
helps catch subtle mistakes where the order of events is not expected,
or the same event happens more than it should.
(I wrote some test helpers, but to avoid early abstraction, I've
intentionally not moved them into a separate module.)
Closes NEXT-1779
### What?
switch turbopack to use a single client components entrypoint for all
client components on a page for development. This aligns it with the
webpack behavior.
### Why?
compiling a separate entrypoint for every client component is pretty
expensive in regards of compilation, chunking, code generation, file
writing and number of requests.
### Turbopack Changes
* https://github.com/vercel/turbo/pull/6713 <!-- Tobias Koppers - use
real emojis -->
* https://github.com/vercel/turbo/pull/6728 <!-- Tobias Koppers - fix
order of reverse topologic iteration -->
Closes PACK-2115
<!-- 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
### 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#58087
-->
fixes#58087
Currently in Next 14, everyone has fullURL flag turned to true, this PR
reverts the condition.
---------
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
### What?
While scrolled on a page, and when following a link to a new page and
clicking the browser back button or using `router.back()`, the scroll
position would sometimes restore scroll to the incorrect spot (in the
case of the test added in this PR, it'd scroll you back to the top of
the list)
### Why?
The refactor in #56497 changed the way router actions are processed:
specifically, all actions were assumed to be async, even if they could
be handled synchronously. For most actions this is fine, as most are
currently async. However, `ACTION_RESTORE` (triggered when the
`popstate` event occurs) isn't async, and introducing a small amount of
delay in the handling of this action can cause the browser to not
properly restore the scroll position
### How?
This special-cases `ACTION_RESTORE` to synchronously process the action
and call `setState` when it's received, rather than creating a promise.
To consistently reproduce this behavior, I added an option to our
browser interface that'll allow us to programmatically trigger a CPU
slowdown.
h/t to @alvarlagerlof for isolating the offending commit and sharing a
minimal reproduction.
Closes NEXT-1819
Likely addresses #58899 but the reproduction was too complex to verify.
## What?
- Add support for `experimental.externalDir` -- Was already supported,
just makes Turbopack not fail on that config option
- Skipped `with-babel` test because it tests Babel
- Skipped `swc-warnings` test because it tests Babel
- Skipped `config-resolve-alias` as it tests webpack config
- Skipped `undefined-webpack-config` as it tests webpack 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 #
-->
Closes NEXT-1817
### What?
Visiting an edge catch-all route incorrectly truncates multiple
parameters
### Why?
The params are currently coerced into a `ParsedURLQuery`-like format by
calling `Object.fromEntries` on `searchParams`, but this doesn't
consider multiple param values assigned to the same key
### How?
Rather than use `fromEntries`, this uses an existing util to get the
path into `ParsedURLQuery` format.
Closes NEXT-1814
Fixes#59333
### What?
When running a
[multi-zone](https://github.com/vercel/next.js/tree/canary/examples/with-zones)
app in dev, app pages would infinitely reload
### Why?
The HMR upgrade request would fail and get caught into a retry loop. In
the multi-zone case, they fail because the upgrade request would be sent
again for a request that had already been upgraded. This resulted in a
"server.handleUpgrade() was called more than once with the same socket"
error, causing the upgrade request to fail.
Every time a retry occurred, the page would trigger a full refresh since
certain HMR errors cause the browser to reload.
### How?
This ensures the upgrade handler only responds to requests that match
the configured basePath.
Closes NEXT-1797
Fixes#59161Fixes#56615Fixes#54454
This makes some critical modifications to the app render pipeline when
PPR has been enabled for pages with segments defining:
```js
export const dynamic = "force-dynamic"
```
Importantly, it no longer modifies the revalidation time to zero for
those pages, and now falls back to the provided default revalidation
time. When static render occurs, if the page being rendered has a
segment config defining `dynamic === "force-dynamic"`, then it will
postpone at the root of the component tree. This ensures that no render
code is executed for the page, as the entirety of the tree will have
postponed. This fixes the bug where the flight prefetch wasn't generated
correctly as well.
Most of them can now be handled by `optimizePackageImports` as I
manually tested them locally. The main benefit is that structural
updates from these libs won't affect our internal configurations
anymore, as they're automatic with the new approach. The little downside
is that the automatic way is a bit slower than the `modularizeImports`
config as it needs to do extra analyzation. But overall, this is a good
direction.
Depends on #59254.
### What?
Using an interception marker next to a dynamic segment does not behave
properly when deployed to Vercel
### Why?
The named route regex that gets created is not accounting for the
interception marker, which is causing the non-intercepted route to match
the intercepted serverless function.
### How?
This factors in the interception marker when building the named route
regex so that the non-intercepted route regex properly matches when
loading the non-intercepted page.
Deployment verified here: https://test-intercept-mu.vercel.app/
Closes NEXT-1786
Fixes#54650
Fixes#57624. The recent issue was an unexpected side effect caused by
305bb01506,
which only affects specific packages like `@mui/material`.
The problem was that the entry file of `@mui/material` has `"use
client"` at top, which affects the compilation result to output
reference info only (when on the RSC layer), instead of keeping the
original export statements. And the fix here is to ignore all layer info
and React specific transforms here, as barrel optimization isn't related
to all these framework features at all. To keep all directives
unchanged, the SWC transform needs to parse and pass that info to the
Webpack loader.
This PR adds a test to ensure that `@mui/material` is working as
expected (less than 1500 modules compiled). Without this feature it'll
be ~2400 modules.
Closes NEXT-1793, closes NEXT-1762.
Adds process.env.__NEXT_PPR as static flag that it gets inlined by
DefinePlugin during build.
This matches what we do for other experiments, but I do wonder, why do
we bother with process.env at all instead of a global __NEXT_PPR symbol?
I'll leave that for later discussion.
Closes NEXT-1792
Similar in spirit to #58938.
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.
The purpose of the `mutable` field was so that if an action is processed
multiple times, state could be reused between each run; for example, to
prevent redundant network fetches. Now that this scenario can no longer
happen, we can remove it.
I had to update some of the unit tests in navigate-reducer because they
were written with the assumption that the reducer was called multiple
times. As far as I can tell, most of this behavior is covered by e2e
tests anyway, so I don't think it's too risky.
Closes NEXT-1782
This resolves an issue introduced in #52361 where `shouldOmit` is
overwritten based on if it is a directory or not without considering
include conditions.
In an environment where the the application being built is orchestrated
and managed by bazel, all files are symbolic links and thus without this
the file includes predicate checks aren't considered - and the build
fails under certain conditions.
<!-- 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: Shu Ding <g@shud.in>
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