## What?
`exportPathMap` didn't work when Turbopack was enabled because the
`serializeNextConfig` function mutates the original values, overriding
`exportPathMap`.
This PR changes the serialization to copy the object and mutate only the
copied object.
Also refactored the test that was checking `_next`, the better way to
test that is to have the page render something dynamically, which is
what is added in this 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 #
-->
Closes NEXT-2225
### What
When users're using nextjs server API that break the build, and error
with incorrect client components usage.
Instrument should be treated as server components or server-only build
target, instead of being treated as client components.
### How
We added a new layer `instrument` for instrument hook bundling, and
apply it with the rsc server webpack loaders
Fixes#57563
Closes NEXT-2181
Closes NEXT-1994
### What?
Interception routes on dynamic paths don't currently work when PPR is
turned on, and instead trigger an MPA navigation to the full route.
### Why?
Route interception relies on the `Next-Flight-Router-State` header to
extract the dynamic params necessary to convert something like
`[locale]`, which would correspond with a URL of `/en`, to something
like `["locale", "en", "d"]`. (See [this
function](fbfd7b5f81/packages/next/src/server/app-render/app-render.tsx (L129-L137))
for more info). When PPR is turned on, we currently ignore this request
header and don't provide it to the functions that render the component
tree.
Without the flight router state, this function bails out and instead
will leave the segment key as `[locale]`. When the client router goes to
diff the current tree on the client with the response from the server,
it will detect a mismatch between the current segment and the incoming
segment, and trigger an MPA navigation in [this
block](fbfd7b5f81/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts (L414-L416)).
### How?
This special-cases interception routes to not strip this header.
Closes NEXT-2215
### What
Fixes the string id that broken when sitemap is optimized to static
route.
### Why
When sitemap is optimized to static route in production, the route
argument is changed from `[[...__metadata_id__]]` to
`[__metadata_id__]`, so the type of it is also changed from array to
string that should reflect in the loader code.
Fixes#60894
Closes NEXT-2154
# Turbopack
* https://github.com/vercel/turbo/pull/7027 <!-- Donny/강동윤 - Update `swc_core` to `v0.87.28` -->
---
### What?
Update swc crates
### Why?
Required for #57718.
`styled-jsx` crate now has a hook to transform CSS code using a
Rust-side API
### How?
Fixes#57718
Closes PACK-2256
### What?
Update terser to the latest version.
### Why?
We need
c677e28526
which adds supports for class static blocks.
### How?
Closes PACK-2285
Fixes#60837
### What
We've had the Next.js version checker in dev overlay of webpack mode.
But it was missing for turbopack. Add it in turbopack mode and also give
a small marker `"(turbo)"` to highlight turbopack mode.
Screenshot
<img width="576" alt="image"
src="https://github.com/vercel/next.js/assets/4800338/1bb1500c-fd92-43bd-a60a-ddc7cd63ce6f">
Closes NEXT-2196
Closes NEXT-2106
formalizes the concept of dynamic APIs inside Next to allow for varying
semantics beyond just staticGenerationBailout.
### Dynamic APIs
#### `markCurrentScopeAsDynamic`
useful to bail out of default caching semantics but does not imply a
Request specific data source was read. critically, this semantic is
ignored if you are inside a cache scope
#### `trackDynamicDataAccessed`
Must be called before reading any data source that is derived from
Request specific data. Currently this is `cookies()`, `headers()`, and
`searchParams`. This kind of data access inside a cache scope is
forbidden (it always should have been, but now it will error).
#### `trackDynamicFetch`
This one is unideal but the complexity of patch-fetch's current
implementation necessitates it for now. Essentially it will postpone if
we are prerendering. Long term this should be eliminated with a refactor
of patch fetch.
### Other Improvements
Also removes the `staticGenerationBailout` implementation as it has been
replaced with more specific logic in the places it was previously being
used.
One area that has also been enhanced is the proxy for app-route modules.
Previously we proxied the Request every time however when we are doing
non-static generation executions we generally don't want the overhead of
wrapping the request. In the refactor here I also improved the runtime
performance by using static proxy handlers and I believe I also fixed a
few bugs related to `clone` and `url`
In general there has been a bit of refactoring to clarify how we should
handle various render/execution states and a reduction in implicit side
effects for proper execution.
Another callout to notice is that app-route modules do not attempt a
static generation if they are force-dynamic regardless of the PPR
setting. Previously the PPR setting would opt them into this code path
which is not necessary because PPR itself does not work for routes, only
pages.
Closes NEXT-2099
fixes NEXT-2173
Fixes#59968
### TODOs
- [x] recreate [repro](https://github.com/williamli/nextjs-NEXT-2173)
- [x] patch `useSelectedLayoutSegment` to support parallel routes (see
"What")
- [x] check `useSelectedLayoutSegments` to see if it is affected
- [x] add test cases
- [x] finalise PR description
### What?
`useSelectedLayoutSegment` does not return the name of the active state
of parallel route slots.
#### Expected Behaviour
According to
https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#useselectedlayoutsegments
> When a user navigates to app/@auth/login (or /login in the URL bar),
loginSegments will be equal to the string "login".
👉🏽 We should update the docs to explain `null` and __DEFAULT__ result as
well.
According to the [API reference for
useSelectedLayoutSegment](https://nextjs.org/docs/app/api-reference/functions/use-selected-layout-segment#returns):
> useSelectedLayoutSegment returns a string of the active segment or
null if one doesn't exist.
> For example, given the Layouts and URLs below, the returned segment
would be:
> <img width="881" alt="CleanShot 2024-01-20 at 14 50 52@2x"
src="https://github.com/vercel/next.js/assets/179761/bfaa34c8-3139-4ec3-bd70-4346c682e36b">
#### Current Behaviour
Currently a string "children" is returned for everything inside a
parallel route with active state and `__DEFAULT__` is returned if there
is no active state for the parallel route (since the `default.tsx` is
loaded). ~`null` is returned when the `default.tsx` is not loaded
(possibly caused by another bug, see test case 5).~
#### Reproduction
[GitHub Repo](https://github.com/williamli/nextjs-NEXT-2173) is created
based on the example provided in [Next.js docs for using
`useSelectedLayoutSegment` with Parallel
Routes](https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#useselectedlayoutsegments).
#### Test Cases
1. If you visit https://next-2173.vercel.app/, you get loginSegments:
__DEFAULT__ (hard navigation) or children (soft navigation after
returning from a visit to /login)
2. If you soft nav to (/app/@auth/login and /app/@nav/login)
https://next-2173.vercel.app/login, you get
1. loginSegment: `children` (expected value should be `login`)
2. navSegment: `children` (expected value should be `login`)
3. If you soft nav to (/app/@auth/reset)
https://next-2173.vercel.app/reset, you get
1. loginSegments: `children` (expected value should be `reset`)
2. navSegment: `children` (expected value should be `login`)
4. If you soft nav to (/app/@auth/reset/withEmail)
https://next-2173.vercel.app/reset/withEmail, you get
1. loginSegments: `children` (expected value should be `withEmail`)
2. navSegment: `children` (expected value should be `login`)
5. ~If you hard nav to (/app/@auth/reset/withEmail)
https://next-2173.vercel.app/reset/withEmail, you get an unexpected
result due to possibly another bug:~
* ~navSegment is `null` on the deployed (Vercel) version, the navSlot is
*not* loaded~
* ~navSegment is `__DEFAULT__` on local dev, the navSlot loads
`/app/@nav/default.tsx`.~
### Why?
In `packages/next/src/client/components/navigation.ts`,
`getSelectedLayoutSegmentPath` is called and returns the correct
segmentPath for parallel routes (even though there is a TODO comment
indicating this function needs to be updated to handle parallel routes)
but `useSelectedLayoutSegment` failed to return the correct segment when
a parallelRouteKey is provided.
### How?
`useSelectedLayoutSegment` is updated to return
selectedLayoutSegments[0] for non parallel routes (original logic), but
it will return the last segments for parallel routes (or null if nothing
is active).
```
return parallelRouteKey === 'children'
? selectedLayoutSegments[0]
: selectedLayoutSegments[selectedLayoutSegments.length-1] ?? null
```
---------
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
This PR adds a warning when attempting to optimize an animated image.
```jsx
<Image src="/image.gif" />
```
The warning looks like the following:
```
The requested resource "/image.gif" is an animated image so it will not be optimized. Consider adding the "unoptimized" property to the <Image>.
```
To remove the warning, add the `unoptimized` prop.
```jsx
<Image src="/image.gif" unoptimized />
```
We don't attempt to optimized animated images because it can be very
slow (30+ seconds) and sometimes deoptimizeds (the output is larger than
the input) so its best to serve the animated image as-is.
Closes NEXT-2199
Fix NEXT-2165
### What?
Addresses the limitation of #60240, where a dummy `default` file is
required in parallel route child slot to prevent errors in dev server
rendering (`TypeError: Cannot read properties of undefined (reading
'clientModules')`) as well as errors in build and deploy (`Error:
ENOENT: no such file or directory, lstat
‘/vercel/path0/.next/server/app/parallel-route/[section]/@part/[partSlug]/page_client-reference-manifest.js’`)
Without the `default.tsx`, builds and deployments will fail with:
<img width="956" alt="CleanShot 2024-01-18 at 02 12 36@2x"
src="https://github.com/vercel/next.js/assets/179761/80ba61bd-6ec0-4b16-a393-dc9375227e19">
local dev server will also crash with:
<img width="986" alt="CleanShot 2024-01-18 at 02 13 19@2x"
src="https://github.com/vercel/next.js/assets/179761/cc500a32-b2f8-47b4-999e-e57cf5141b2f">
> TypeError: Cannot read properties of undefined (reading
'clientModules')
### Why?
Since `default.tsx` is not a compulsory when you have slot that are
specific and ends with a dynamic route segment, this PR extends support
so that it is possible mixing catch-all routes with specific
non-catchall routes without requiring an additional `default.tsx` .
This PR will allow the following test cases to pass:
```
it('should not add the catch-all route to segments that have a more specific [dynamicRoute]', () => {
const appPaths = {
'/': ['/page'],
'/[[...catchAll]]': ['/[[...catchAll]]/page'],
'/nested/[foo]/[bar]/default': [
'/nested/[foo]/[bar]/default',
'/nested/[foo]/[bar]/@slot0/default',
'/nested/[foo]/[bar]/@slot2/default',
],
'/nested/[foo]/[bar]': [
'/nested/[foo]/[bar]/@slot0/page',
'/nested/[foo]/[bar]/@slot1/page',
],
'/nested/[foo]/[bar]/[baz]': [
'/nested/[foo]/[bar]/@slot0/[baz]/page',
'/nested/[foo]/[bar]/@slot1/[baz]/page',
],
'/[locale]/nested/[foo]/[bar]/[baz]/[qux]': [
'/[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page',
],
}
const initialAppPaths = JSON.parse(JSON.stringify(appPaths))
normalizeCatchAllRoutes(appPaths)
expect(appPaths).toMatchObject(initialAppPaths)
})
...
```
```it('should not add the catch-all route to segments that have a more specific [dynamicRoute]', () => {
const appPaths = {
'/': ['/page'],
'/[[...catchAll]]': ['/[[...catchAll]]/page'],
'/nested/[foo]/[bar]/default': [
'/nested/[foo]/[bar]/default',
'/nested/[foo]/[bar]/@slot0/default',
'/nested/[foo]/[bar]/@slot2/default',
],
'/nested/[foo]/[bar]': [
'/nested/[foo]/[bar]/@slot0/page',
'/nested/[foo]/[bar]/@slot1/page',
],
'/nested/[foo]/[bar]/[baz]': [
'/nested/[foo]/[bar]/@slot0/[baz]/page',
'/nested/[foo]/[bar]/@slot1/[baz]/page',
],
'/[locale]/nested/[foo]/[bar]/[baz]/[qux]': [
'/[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page',
],
}
...
```
and allow parallel routes defined in this [code
repro](https://github.com/williamli/nextjs-NEXT-2165) to build.
![image](https://github.com/vercel/next.js/assets/179761/030f4fe1-3a27-41e5-bbd9-bc511f95e5d7)
### How?
`packages/next/src/build/normalize-catchall-routes.ts` is extended to
check `appPath` to see if it is:
1. the route is not a catchall
2. `isMoreSpecific` than the closest `catchAllRoute`.
where `isMoreSpecific` is defined as:
```
function isMoreSpecific(pathname: string, catchAllRoute: string): boolean {
const pathnameDepth = pathname.split('/').length
const catchAllRouteDepth = catchAllRoute.split('/').length - 1
return pathnameDepth > catchAllRouteDepth
}
```
---------
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
## What?
Implements https://github.com/vercel/turbo/pull/7081. Ensures image
imports in the edge runtime have the correct asset url. Previously it
would be `/assets/file.hash.png` but it should be
`/_next/static/media/file.hash.png`.
Updates the image tests to correctly compare the values in Turbopack and
the values in Webpack. Currently it only checks webpack values, causing
the tests to fail in Turbopack.
<!-- 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-2194
### What?
`ANALYZE=1` is set in CI, but this shouldn't emit stats.
### Why?
It sometimes causes the `lint` step to fail as prettier checks these
stats files too
Closes PACK-2280
### What & Why?
Interception routes depend on contextual information that are provided
via request headers. Specifically it needs to know about the
`Next-Router-State-Tree` when generating the interception route RSC
data, which isn't available at build time. This doesn't currently cause
any usage issues, but it erroneously emits static files & RSC payloads
that the client router won't be able to use and will instead fallback to
a dynamic request.
I removed some special case in an existing test since this fix also
resolves a discrepancy in behavior when PPR is turned on
### How?
This excludes interception routes from `appStaticPaths` at builds which
currently determines which pages should be statically generated.
Closes NEXT-2190
### Description
This PR refactors existing `analysis/get-static-page-info`, moves over
most of parse / ast visiting logic into next-swc's rust codebase. By
having this, turbopack can reuse same logic to extract info for the
analysis. Also as a side effect, this removes JS side parse which is
known to be inefficient due to serialization / deserialization.
The entrypoint `getPageStaticInfo` is still in the existing
`get-page-static-info`, only for extracting / visiting logic is moved.
There are some JS specific context to postprocess extracted information
which would require additional effort to move into.
Closes PACK-2088
In both dev server and production build we both use `getStartServerInfo`
to log the basic info but for prod build we should always respect to use
"build" phase
Fixes#57927
Closes NEXT-2179
This:
- Makes makes reporting hmr changes more accurate by emitting an
explicit start event and lowering the aggregation period for reporting
completed turbo tasks
- Parameterizes the aggregation period, allowing JS subscribers to
request different intervals, such as for the next-rs-api test
- Aligns path pattern with webpack by normalizing its layer names
- Fixes a bug in `drainAndGetNext` where the stream never could drain
past the first item
- Sends `client-hmr-latency` spans from Turbopack in both page and app
router pages
Closes PACK-2252
---------
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
The PR continues from #58038 aiming to reduce the installation size
further, and **improve performance in doing so**.
Most of `micromatch`'s APIs are essentially wrappers/alias of
`picomatch`, supplemented with additional features facilitated by a
transitive dependency `braces`. However, Next.js doesn't use those
"extra features". Switching from `micromatch` to `picomatch` can avoid
introducing the transitive dependency `braces`.
The PR also improves some globs' performance by hoisting.
- `micromatch.makeRe` is just an alias of `picomatch.makeRe`
-
90dc0cd3e1/index.js (L387C30-L387C30)
- `micromatch.isMatch(str, patterns, options)` equals
`picomatch(patterns, options)(str)`
-
90dc0cd3e1/index.js (L123)
- `micromatch.matcher` is just an alias of `picomatch`
-
90dc0cd3e1/index.js (L104C1-L104C40)
---------
Co-authored-by: Sam Ko <sam@vercel.com>
### 🧐 What's in there?
`config.analyticsId` is a rarely-used mechanism, initially intended to
Next.js users hosting their application themselves and willing to report
Core Web Vitals to Vercel Speed Insights.
This platform specific mechanism can be replaced with the built-in
[`useReportWebVitals`](https://nextjs.org/docs/app/api-reference/functions/use-report-web-vitals).
### 🧪 How to test?
1. make a new Next.js app
1. define env variable `VERCEL_ANALYTICS_ID` to a dummy value
1. start your application in dev mode:
```shell
⚠ config.analyticsId is deprecated and will be removed in next major
version. Read more:
https://nextjs.org/docs/messages/deprecated-analyticsid
▲ Next.js 14.0.5-canary.58
- Local: http://localhost:3000
✓ Ready in 917ms
```
1. build your application:
```shell
▲ Next.js 14.0.5-canary.58
Creating an optimized production build ...
✓ Compiled successfully
Linting and checking validity of types .
⚠ The Next.js plugin was not detected in your ESLint configuration. See
https://nextjs.org/docs/basic-features/eslint#migrating-existing-config
✓ Linting and checking validity of types
✓ Collecting page data
✓ Generating static pages (4/4)
⚠ `config.analyticsId` is deprecated and will be removed in next major
version. Read more:
https://nextjs.org/docs/messages/deprecated-analyticsid
```
1. remove the env variable, add a `next.config.js` file with a dummy
`analyticsId` variable:
```js
module.exports = { analyticsId: "UA-12345678-9" };
```
1. start your application in dev mode: it'll issue the same warning.
1. build your application: it'll issue the same warning.
---------
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
It seems that when tracing build dependencies our server tracing was
analyzing all server chunks un-necessarily and when a very large
dependency like `ace-builds` is creating large chunks it can slow down
builds drastically so this ensures we eagerly apply our shared ignores
to avoid this over tracing.
Build times before [with provided
repro](https://github.com/MartinXPN/next-slow-build-reproduction):
```sh
▲ Next.js 14.1.0
Creating an optimized production build ...
✓ Compiled successfully
✓ Linting and checking validity of types
✓ Collecting page data
✓ Generating static pages (5/5)
✓ Collecting build traces
✓ Finalizing page optimization
✨ Done in 437.29s.
```
Build times after [with provided
repro](https://github.com/MartinXPN/next-slow-build-reproduction):
```sh
▲ Next.js 14.1.1-canary.0
Creating an optimized production build ...
✓ Compiled successfully
✓ Linting and checking validity of types
✓ Collecting page data
✓ Generating static pages (5/5)
✓ Collecting build traces
✓ Finalizing page optimization
✨ Done in 42.38s.
```
Closes: https://github.com/vercel/next.js/issues/58759
Closes NEXT-2161
Issue: https://github.com/vercel/next.js/issues/60853
### What?
Added `@sentry/profiling-node` to the server-external-package object so
that sentry users who want to use this package don't have to manually
add this package in the experimental nextjs config entry.
### Why?
Package bundling will fail as shown in the following issue if not added
to this exclude list.
https://github.com/getsentry/profiling-node/issues/170
---
Fixes#60853
`experimental.missingSuspenseWithCSRBailout` should be enabled by
default to help users to disciver unwrapped suspense boundaries.
Add more notes in the error doc about deprecation and temporary
workaround to disable it.
Closes NEXT-2157
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>