This introduces an experimental router flag (`experimental.staleTimes`)
to change the router cache behavior. Specifically:
```ts
// next.config.js
module.exports = {
experimental: {
staleTimes: {
dynamic: <seconds>,
static: <seconds>,
},
},
};
```
- `dynamic` is the value that is used when the `prefetch` `Link` prop is
left unspecified. (Default 30 seconds)
- `static` is the value that is used when the `prefetch` `Link` prop is
`true`. (Default 5 minutes)
Additional details:
- Loading boundaries are considered reusable for the time period
indicated by the `static` property (default 5 minutes)
- This doesn't disable partial rendering support, **meaning shared
layouts won't automatically be refetched every navigation, only the new
segment data**.
- This also doesn't change back/forward caching behavior to ensure
things like scroll restoration etc still work nicely.
Please see the original proposal
[here](https://github.com/vercel/next.js/discussions/54075#discussioncomment-6754339)
for more information. The primary difference is that this is a global
configuration, rather than a per-segment configuration, and it isn't
applied to layouts. (We expect this to be a "stop-gap" and not the final
router caching solution)
Closes NEXT-2703
### What?
This fixes an issue where the `nonce` attribute isn't set on
`next/script` elements that has the `afterInteractive` (the default)
strategy resulting in `<link rel="preload" as="script"/>` tags without a
nonce.
### Why?
For apps that uses 3rd party scripts (or any script) with a nonce loaded
via `next/script` this is necessary unless you want them all to use
`beforeInteractive` which isn't super nice for performance.
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
### What & Why
There was some code added in the catch-all route normalization that
doesn't seem to make sense -- it was checking if the provided `appPath`
depth was larger than the catch-all route depth, prior to inserting it.
But it was comparing depths in an inconsistent way (`.length` vs
`.length - 1`), and the catch all path was also considering the `@slot`
and `/page` suffix as part of the path depth.
This means that if you had a `@modal/[...catchAll]` slot, it wouldn't be
considered for a page like `/foo/bar/baz`, because `/foo/bar/baz`
(depth: 4 with the current logic) and `/@modal/[...catchAll]/page`
(depth: 3 with the current logic) signaled that the `/foo/bar/baz` route
was "more specific" and shouldn't match the catch-all.
I think this was most likely added to resolve a bug where we were
inserting optional catch-all (`[[...catchAll]]`) routes into parallel
slots. However, optional catch-all routes are currently unsupported with
parallel routes, so this feature didn't work properly and the partial
support introduced a bug for regular catch-all routes.
### How
This removes the confusing workaround and skips optional catch-all
segments in this handling. Separately, we can add support for optional
catch-all parallel routes, but doing so will require quite a bit more
changes & also similar handling in Turbopack. Namely, if have a
top-level optional catch-all, in both the Turbopack & current Webpack
implementation, that top-level catch-all wouldn't be matched. And if you
tried to have an optional catch-all slot, in both implementations, the
app would error with:
> You cannot define a route with the same specificity as a optional
catch-all route ("/" and "/[[...catchAll]]")
because our route normalization logic does not treat slots specificity
differently than pages.
**Note**: This keeps the test that was added when this logic was first
introduced in #60776 to ensure that the case this was originally added
for still passes.
Fixes#62948
Closes NEXT-2728
Closes: https://github.com/vercel/next.js/issues/63623
When a relative assetPrefix was set (e.g. `/custom-asset-prefix`),
bundle fetching would always return a 404 as the assetPrefix was not
removed from filesystem path
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
<!-- 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?
Fixes#63871
-->
### What?
Adds safe traversal to rewrite `has` items in a certain new
(`isInterceptionRouteRewrite()` added in the v14.2.0 canaries) check to
the rewrite routes.
### Why?
The new check assumed that all `has` arrays had at least one item, when
previously Next.js accepted rewrites with empty `has`. Adding safe
traversal doesn't negatively impact the check, as the check only needs
rewrites with the first item.
Fixes#63871
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
### What
Strip the search query for the `urlPathname` passed down to metadata
handling.
### Why
This is because the `urlPathname` from `staticGenerationStore` contains
query, so it will contain `?rsc` query for client navigation, which lead
to the relative path canonical url (e.g. `./`) will have the search
query along with it. This PR is to remove that and make sure always uses
pathname.
Reported by @pacocoursey
Closes NEXT-2963
### What & Why
When an RSC triggers `navigate` after the shell has already been sent to
the client, a meta tag is inserted to signal to the browser it needs to
perform an MPA navigation. This is primarily used for bot user agents,
since we wouldn't have been able to provide a proper redirect status
code (since it occurred after the initial response was sent).
However, the router would trigger a SPA navigation, while the `<meta>`
tag lagged to perform an MPA navigation, resulting in 2 navigations to
the same URL.
### How
When the client side code attempts to handle the redirect, we treat it
like an MPA navigation. This will suspend in render and trigger a
`location.push`/`location.replace` to the targeted URL. As a result,
only one of these navigation events will win.
Fixes#59800Fixes#62463
Closes NEXT-2952
Closes NEXT-2719
When a server action performs a redirect, we currently initiate a `HEAD`
request to the targeted URL to verify if it has a proper RSC response.
If it does, it then invokes a GET and streams the response. This leads
to an extra request to the server which can be costly and poor for
performance. If the `GET` returns an invalid RSC response, we'll discard
the response. The client router will also see the invalid response which
will signal that it needs to perform an MPA navigation to the targeted
URL.
<!-- 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-2956
### What
When calling `revalidatePath` or `revalidateTag` in a server action for
an intercepted route with dynamic segments, the page would do a full
browser refresh.
### Why
When constructing rewrites for interception routes, the route params
leading up to the interception route are "voided" with a
`__NEXT_EMPTY_PARAM__` demarcation. When it comes time to look up the
values for these dynamic segments, since the params aren't going to be
part of the URL, they get matched via `FlightRouterState`
([ref](d67d658ce7/packages/next/src/server/app-render/app-render.tsx (L153-L201))).
The `shouldProvideFlightRouterState` variable only passes it through for
RSC requests; however, since the server action will perform the action &
return the flight data in a single pass, that means the updated tree
from the server action isn't going to receive the `FlightRouterState`
when constructing the new tree. This means the old tree will have a
`["locale", "en", "d"]` segment, and the new tree from the server action
will have `"[locale]"`. When the router detects this kind of segment
mismatch, it assumes the user navigated to a new root layout, and
triggers an MPA navigation.
### How
This unconditionally provides the `FlightRouterState` to
`makeGetDynamicParamFromSegment` so that it can properly extract dynamic
params for interception routes. We currently enforce interception routes
to be dynamic due to this `FlightRouterState` dependency.
Fixes#59796
Closes NEXT-2079
`applyRouterStatePatchToTree` had been refactored to support the case of
not skipping the `__DEFAULT__` segment, so that `router.refresh` or
revalidating in a server action wouldn't break the router. (More details
in this #59585)
This was a stop-gap and not an ideal solution, as this behavior means
`router.refresh()` would effectively behave like reloading the page,
where "stale" segments (ones that went from `__PAGE__` -> `__DEFAULT__`)
would disappear.
This PR reverts that handling. The next PR in this stack (#63608) adds
handling to refresh "stale" segments as well.
Note: We expect the test case that was added in #59585 to fail here, but
it is re-enabled in the next PR in the stack.
Note 2: #63608 was accidentally merged into this PR, despite being a
separate entry in the stack. As such, I've copied the issues from that
PR into this one so they can be linked. See the notes from that PR for
the refresh fix details.
Fixes#60815Fixes#60950Fixes#51711Fixes#51714Fixes#58715Fixes#60948Fixes#62213Fixes#61341
Closes [NEXT-1845](https://linear.app/vercel/issue/NEXT-1845)
Closes [NEXT-2030](https://linear.app/vercel/issue/NEXT-2030)
<!-- 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-2903
### What
In static generation phase of app page, if there's any case that we're
receiving 3xx/4xx status code from the response, we 're setting it into
the static generation meta now to make sure they're still returning the
same status after build.
### Why
During static generation if there's any 3xx/4xx status code that is set
in the response, we should respect to it, such as the ones caused by
using `notFound()` to mark as 404 response or `redirect` to mark as
`307` response.
Closes NEXT-2895
Fixes#51021Fixes#62228
Recently the serverActionReducer was updated to no longer use React's
thenable type to carry resolution/rejection information. However the
rejection reason was not updated so now when a server action fails we
were rejecting with `undefined` rather than the rejected reason. This
change updates the reject to use the rejection value.
Closes NEXT-2943
This ensures that even if a `loading.js` returns `null`, that we still
render a `Suspense` boundary, as it's perfectly valid to have an empty
fallback.
This was accidentally lost in #62346 -- this brings back the
`hasLoading` prop which will check the loading module itself (rather
than the `ReactNode`) for truthiness, and I've added a test to avoid
another regression.
<!-- 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-2936
### What
* Remove the erroring of force-dynamic is not able to use during static
generation
* Export the route segments properly in sitemap conventions
### Why
We discovered this error is showing up when users are using
force-dynamic with generating multi sitemaps.
When you have a dynamic `route /[id]/route.js` , and you have
generateSitemaps defined which is actually using `generateSitemaps`
under the hood , then you set the route to dynamic with `export dynamic
= 'force-dynamic'`.
We should keep the route still as dynamic. `generateStaticParams` is
only for generating the paths, which is static in build time. And the
`force-dynamic` is going to be applied to each generated path.
Closes NEXT-2881
### What
Actions that revalidate the router state by kicking off a refetch (such
as `router.refresh()` or dev fast refresh) would incorrectly trigger an
interception route if one matched the current URL, or in the case of
already being on an intercepted route, would trigger the full detail
page instead.
### Why
Interception rewrites use the `nextUrl` header to determine if the
requested path should be rewritten to a different path. We currently
forward that header indiscriminately, which means that if you were on a
non-intercepted route and called `router.refresh()`, the UI would change
to the intercepted content instead (since it would treat it the same as
a soft-navigation).
### How
This updates various reducers to only forward the `nextUrl` header if
there's an interception route present in the tree. If there is, we want
to refresh its data, rather than the data for the underlying page. The
reverse is also true: if we were on the "full" page, and triggered a
`router.refresh()`, we won't forward `nextUrl` meaning it won't fetch
the interception data.
In order to determine if an interception route is present in the tree, I
had to add a new segment type for dynamic interception routes, as by the
time they reach the client they are stripped of their interception
marker.
**Note: There are a series of bugs related to `router.refresh` with
parallel/interception routes, such as the previous page/slot content
disappearing when triggering a refresh. This does not address all of
those cases, but I'm working through them!**
Fixes#60844Fixes#62470
Closes NEXT-2737
Currently when we generate payloads in app router, the order of RSC
chunks aren't deterministic even if the content stays the same. This
means that any caches that rely on etags for detecting changes in
content aren't able to reliably cache/and avoid invalidating properly.
To avoid this we can manually sort the content before generating the
etag. Eventually this can be fixed upstream in react although that is a
bigger lift so we are doing this for now to alleviate the issue.
x-ref: [slack
thread](https://vercel.slack.com/archives/C042LHPJ1NX/p1709937748240119?thread_ts=1709856182.174879&cid=C042LHPJ1NX)
Closes NEXT-2825
In #61573, I updated the navigation reducer to request a new prefetch
entry if it's stale. But this has the unintended consequence of making
instant loading states effectively useless after 30s (when the prefetch
would have expired). Blocking navigation and then rendering the loading
state isn't ideal - if we have some loading data in a cache node, we
should re-use it.
Now that #62346 stores loading data in the `CacheNode`, we can copy over
`loading` during a navigation.
This PR repurposes `fillCacheWithDataProperty` which wasn't being used
anywhere, to instead be a utility we can use to programmatically trigger
a lazy fetch on a particular segment path by nulling out it's data while
copying over other properties. We could have used the existing util
as-is, but ideally we only have a single spot where lazy fetching can
happen, which currently is in `LayoutRouter`.
When a stale prefetch entry is detected, rather than applying the data
to the tree, this PR will copy over the `loading` nodes and will
"delete" the data so it can be refetched.
<!-- 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-2806
### What?
This fixes more CSS ordering issues with production and webpack dev.
* CSS Modules must not be side effect free as side effect free modules
are per definition order independent which is not true for CSS
* fix order of iterating module references
* disable splitChunks for CSS
* special chunking for CSS with loose and strict mode
* more test cases
Closes PACK-2709
### What?
* Allow to apply webpack loaders depending on "conditions".
* add a few next specific conditions depending on context type
### Why?
Some loaders need different behavior depending on context
### How?
Closes PACK-2748
### What?
* rename test case
* improve error message and handle edge case for require resolving
* fix test case actually testing externals (webpack was silently
bundling, Turbopack showed error that helped to find the broken test
case)
### Why?
### How?
Closes PACK-2662
### What
When a route handler uses an API that opts it into dynamic rendering
(such as `no-store` on a fetch), and also specifies a `revalidate` time,
the `revalidate` time is ignored and route is treated as fully static.
### Why
`revalidate: 0` and `revalidate: false` have different semantic
meanings: `false` essentially means cache forever, whereas `0` means
it's dynamic. Since `0` is also falsey, the code we have to fallback
with a default `revalidate` value for route handlers is incorrectly not
marking the route as dynamic, and as a result, caching the route without
an expiration time.
### How
This updates the fallback handling for app routes respect a revalidation
value of `0`, so that the page can properly be marked dynamic.
### Test Explanation
This adds 2 new routes handlers: both have a revalidation time specified
& use `no-store` on a fetch, but only one of them specifies `export
const dynamic = 'force-static'`. The one that doesn't specify
`force-static` is correctly omitted from the prerender manifest. The one
that is `force-static` is correctly in the prerender manifest with the
right expiration time. An additional test case was added to verify that
this data refreshes after the specified interval.
Closes NEXT-2764
Addresses some feedback in #62821. This will re-allow implementations
like:
```js
'use server'
export const f = wrapper(async () => {})
```
Where `wrapper` creates a sync function that returns a promise. Although
it will still be silently converted to an async function under the hood.
Closes NEXT-2790
This ensures we properly catch/handle `generateMetadata` errors during
eager evaluating of nested `generateMetadata` functions in the tree.
Previously if we eager evaluated a child metadata function that threw an
error e.g. `notFound()` and but the parent metadata function took longer
the thrown error would be an unhandled rejection causing the process to
crash depending on the environment.
Fixes: NEXT-2588
Closes NEXT-2786
### What?
make sure that we don't error for dynamic requests on server side.
It will throw at runtime when using a dynamic request.
### Why?
Not all packages are fully bundler compatible, but still work when only
using the parts that work. We don't want to block users from using them
by having an hard compile error.
### How?
Closes PACK-2675
<!-- 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 #
-->
The value `undefined` can be saved to the incremental cache as
`undefined` (`JSON.stringify(undefined)`) with no errors, but when
retrieving it, we attempt to parse it as JSON using
`JSON.parse(undefined)`. This throws an error. We should instead
deserialize `undefined` as `undefined` when retrieving.
relevant discussion: #59087
---------
Co-authored-by: Sam Ko <sam@vercel.com>
### What
Exclude the cases like external urls and relative urls with query from
appending trailing slash when it's needed.
The process is:
- If it's a uncertain string path (relative url, could start with `'./'`
or `/`), convert to relative that starts with `/`;
- then we covert the url (string or URL) to string url
- We do the check if we need to append the trailing slash
### Why
In #62109 we added functionality that can only append trailing slash
when we appended trailing slash to some metadata url like `canonical`
url and open graph url when the config is enabled.
For urls with queries, the trailing slash can also be omitted.
For the external urls (different origin comparing to `metadataBase`) we
don't need to append trailing slash as they're not the same web app.
x-ref: [slack
thread](https://vercel.slack.com/archives/C0676QZBWKS/p1709845946033929)
Closes NEXT-2762
Closes NEXT-2753
Gives the users pathname context on routes that access Dynamic API's so
that if these errors are caught they can modify their code accordingly.
This is a followup to #61332.
Closes NEXT-2695
We didn't set the property of manifest before, this PR fixes the missing
prop
> If the manifest requires credentials to fetch, the crossorigin
attribute must be set to use-credentials, even if the manifest file is
in the same origin as the current page.
x-ref: https://developer.mozilla.org/en-US/docs/Web/Manifest
Fixes NEXT-2706
As mentioned in the new-added error messages, and the [linked
resources](https://react.dev/reference/react/use-server#:~:text=Because%20the%20underlying%20network%20calls%20are%20always%20asynchronous%2C%20%27use%20server%27%20can%20only%20be%20used%20on%20async%20functions.):
> Because the underlying network calls are always asynchronous, 'use
server' can only be used on async functions.
> https://react.dev/reference/react/use-server
It's a requirement that only async functions are allowed to be exported
and annotated with `'use server'`. Currently, we already have compiler
check so this will already error:
```js
'use server'
export function foo () {} // missing async
```
However, since exported values can be very dynamic the compiler can't
catch all mistakes like that. We also have a runtime check for all
exports in a `'use server'` function, but it only covers `typeof value
=== 'function'`.
This PR adds a stricter check for "use server" annotated values to also
make sure they're async functions (`value.constructor.name ===
'AsyncFunction'`).
That said, there are still cases like synchronously returning a promise
to make a function "async", but it's still very different by definition.
For example:
```js
const f = async () => { throw 1; return 1 }
const g = () => { throw 1; return Promise.resolve(1) }
```
Where `g()` can be synchronously caught (`try { g() } catch {}`) but
`f()` can't even if they have the same types. If we allow `g` to be a
Server Action, this behavior is no longer always true but depending on
where it's called (server or client).
Closes#62727.