## 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
Closes PACK-2284
This PR upgrades `upload/download-artifact` action to the latest
version. Per its claim, it can be faster 90% compare to the current in
worst case use case.
Below's comparision between this PR vs. current branch for the datadog
report
![image](https://github.com/vercel/next.js/assets/1210596/f3db6f4d-e137-4013-9745-b8fa55ba1014)
![image](https://github.com/vercel/next.js/assets/1210596/08734620-8530-4b6e-bd09-a5414c703c06)
Cuts download time meaningfully different. Since we use upload/download
in other places as well (i.e download next-swc binary) overall CI time
would be improved.
The challenage is artifact@v4 introduced breaking changes to not to
allow implicitly merge upload / download with duplicated name. PR
introduced unique key for those, then apply download with pattern &
merge.
Hello,
This PR resolves a file extension inconsistency in the 'Setting up
Vitest with Next.js' section of the Next.js documentation
(`01-vitest.mdx`).
When using next.js with JavaScript, following the
documentation(`01-vitest.mdx`) leads to issues during testing because of
the jsx extension.
This PR corrects an example code that wrongly uses a '.js' extension for
a React component, which is against Vitest's requirement for '.jsx'
extensions.
- https://github.com/vitest-dev/vitest/issues/1564
Thank you.
Co-authored-by: Sam Ko <sam@vercel.com>
### What?
The import alias had no way to resolve the page extensions and we
already have them resolved in the `PagesStructure`, so with this PR we
use the already resolved paths.
Closes PACK-2085
Fixes#59264
### What?
This fixes 2 issues with app 404 pages.
1. The root layout in a group was previously ignored when hitting the
404 page.
2. The default app 404 page was missing the correct path for dev
`/not-found` so it would fall back to the pages 404 page.
Closes PACK-2241
Fixes#60688
### 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
This PR improves the Server Actions SWC transform to make it able to
handle nested Action declarations (check
`fixture/server-actions/server/28/input.js` for more details).
It is also a simplification of that transform's internal states and
methods, with the removal of an extra AST pass
(`stmts.visit_mut_with(&mut ClosureActionReplacer {
replaced_action_proxies: &self.replaced_action_proxies, })`). The
generated code is also smaller in some cases. So overall I'd expect the
compilation and runtime performance to improve as well.
## Details
With this change, we're now using `self.declared_idents` and
`self.names` to track closure arguments. `declared_idents` keeps the
identifiers **declared** in the current closure and above. `names` keeps
identifiers **appeared** in the current closure and above. In an example
of the following cursor:
```ts
let x
async function foo() {
"use server"
let y
async function bar() {
"use server"
let z
console.log(x, y, z)
}
// <- cursor
}
```
`declared_idents` would be `y` (`x` isn't in a closure), and `names`
would be `x, y, z`. By manipulating these two states we're able to track
closure closed-up variables recursively.
Closes NEXT-2189
### 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
## What?
Fixes `should have <head> containing <meta name=\"viewport\"> followed
by <link rel=\"preload\"> for priority image` and `should add a blur
placeholder a statically imported x` (where x is a file format) 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-2216
# 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?
In this PR #60988, I think (please correct me if I'm wrong) it was meant
to block GitHub reproduction links like `https://github.com/username` &
`https://github.com`. However, the last regex `github.com` will block
all the github.com links
### Why?
So that people can use a GithHb repo as reproduction link
### How?
Fix the regex, from `github.com` to `github.com$`
Co-authored-by: Steven <steven@ceriously.com>