Users that experiment with PPR and might have seen #61798, or #62703, or
most recently #65483, may try the `__nextppronly=1` query param to debug
the static shell. This will lead to the following uncaught error and
blank page:
<img width="1045" alt="static shell debugging hydration error"
src="https://github.com/vercel/next.js/assets/761683/ed382d97-82ae-4a23-9930-bb4d4419e88e">
It might not be immediately obvious that javascript must be disabled to
see the static shell. To improve the DX in this scenario we can omit the
bootstrap script to skip hydration, and thus prevent the error. Then
debugging the static shell works even without disabling javascript in
the devtools.
<img width="1045" alt="static shell debugging without hydration"
src="https://github.com/vercel/next.js/assets/761683/57f6cb88-f5b4-473f-963f-7fda8c8e7f00">
In addition, we should add the closing body and html tags to the shell
so that a valid HTML document is returned.
`node_modules` gets ignored when deployed unless explicitly allowed, and
the regular install command will clobber what was in there.
This allowlists the `node_modules` directory and copies it into a new
folder, runs the install command, and then merges the patched
`node_modules` in so the patched modules are available in the test.
Only 1 test suite in this suite is failing and it's related to file
tracing, which should be fixed in a follow-up. For now this enables
deploy tests for everything else to make sure we don't regress.
This also simplifies the original test to not require stopping the
server & patching a file.
- Fixed redirects tests not working when deployed because they were
`POST` requests to a static page
- Skipped 404 test for a similar reason: a `POST` to the static not
found page is handled differently, and we won't have access to the
runtime logs anyway
- Refactored interception routes test to not rely on runtime logs
- Fixed revalidation test & removed comment about flakiness
<details>
<summary>Validated Run Summary</summary>
![CleanShot 2024-06-13 at 13 45
32@2x](https://github.com/vercel/next.js/assets/1939140/8b85cb60-b389-451c-b449-41067f86a8d3)
</details>
These 2 tests use an in-memory data store that won't be necessarily
shared across invocations of the lambda. This skips the tests that rely
on that functionality as testing it in `next start` should be
sufficient.
This test was only failing because `vercel logs` limit the output to 100
lines, and telemetry debugging was adding a lot of verbosity to the
build logs.
This bumps the log lines to a higher value to give some more breathing
room, and did a drive-by `check` -> `retry` refactor.
This disables tests that should not be run in a deployed environment,
because they use incompatible APIs or there's no reason to test them
outside of `next start`. Specifically disables for things like:
- Using `next.patchFile`, `next.renameFile`, etc.
- Attempting to use `next.cliOutput` to query runtime logs. When
deployed, these are only build-time logs.
[Latest Run](https://github.com/vercel/next.js/actions/runs/9483807368)
- `next.cliOutput` will only refer to build time logs, so this
particular assertion won't work
- Drive-by refactor for it to use `retry` instead of `check`
Verified this passes when deployed
[Test
Run](https://github.com/vercel/next.js/actions/runs/9471783416/job/26095882422)
Changes:
- Add a setup step that clears the project so it doesn't happen in each
runner
- Run when a release is published rather than on cron
- Notify via Slack when a failure occurs
- Leverage build_reusable for the test runner to match the
build_and_test workflow
- Fixes to `next-deploy` script: not properly logging/catching errors
- Adds manifest to ignore known issues
- Split into 6 runners with 2 concurrency (12 deploys at a time)
- Adds some logging so we know what's happening
- Disable Playwright trace mode (it kept failing to find a trace file
and cluttering the output. Don't think we need it here anyway)
<details>
- <summary>Removed noisy output</summary>
![CleanShot 2024-06-10 at 14 08
05@2x](https://github.com/vercel/next.js/assets/1939140/f227e71c-95b4-4859-90de-a23c88c55ea8)
</details>
<!-- 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?
This modifies the static generation store to instead store a `url`
object with the `pathname` and `search` properties. This corrects the
previous behaviour which used the variable `urlPathname` which had
ambiguous meanings as it technically contained the search string as
well, not just the pathname.
In cases during the app render, this still grabs the contents of
`url.pathname + url.search` (where `url.search` always has a leading `?`
if it has any query parameters, [see the
docs](https://developer.mozilla.org/en-US/docs/Web/API/URL/search)) so
that it emulates the current behaviour. This allows more specific access
though, where now additional parsing can be eliminated which had to
strip the query string off of the `urlPathname` in a few places, and
more worrisome, still accidentally contained the search string causing
errors.
### How?
This requires an upstream fix (#64088) which corrected a bug with the
store access which had caused some previous test failures (accessing
`store.url.pathname` was throwing as `store.url` was undefined on the
wrong return, check the upstream PR for more details on that).
This also changes out usage of `pagePath` with `route`, and lets it be
the fallback (for debugging and error messaging). During static
generation, we will provide a value for the page being rendered that's
correlated to the particular file on the filesystem that the route is
based on:
```
// rendering app/users/[userID]/page.tsx
page: /users/[userID]
pathname: /users/1, /users/2, etc
```
The `route` is used only for debugging, such as when
`generateStaticParams` incorrectly calls `headers()`.
This also moves the pathname from the `staticGenerationStore` into the
`requestStore`, as it's tied to a given request.
Closes NEXT-2965
Closes [#66650](https://github.com/vercel/next.js/issues/66650)
Closes NEXT-3520
### What?
- Make Link not throw during prefetch if it received an invalid `href`
(see [#66650](https://github.com/vercel/next.js/issues/66650))
- Throw in dev mode if an invalid link was passed to `router.prefetch`
-- this matches current prod behavior
- (previously, we'd immediately exit out of `router.prefetch`, so the
user would see no indication that this'd fail in prod)
### Why?
If an invalid URL was passed to `<Link>`, the whole app would crash and
show "A client-side exception occurred". A failed prefetch should not
bring down the whole app.
Note that This preserves the current behavior of explicit
`router.prefetch(url)` throwing an error if `url` is invalid. We may
want to adjust this in the future, but that could be considered a
breaking change, so I'm leaving it out for now. This only affects
`Link`, which was intended to catch any errors thrown from
`router.prefetch`, but that bit was accidentally broken.
### What
Add new test case where a named export from client component is being
exported as page
### Why
We found this case while investigating the errors triggered introduced
by #66286 , adding this test to avoid future regression
### What
Use `addDependency` to track the file path passed to
`next-metadata-route-loader`
NOTE: We cannot apply the `next-metadata-route-loader` directly to the
metatda convention source files, since the json file could be processed
by json loader (Related previous fix#62615)
### Why
Previously when we passed down the file path as argument to the loader,
which sort of breaking the caching of webpack as the actual resource
path is string, it's not tracked as a dependency. This change fixed the
bad caching issue of static metadata routes. Based on the above reason
we use `addDependency` here to track the dependency change
Closes NEXT-3521
Closes#65755
This fixes some tests so that they can run on macOS that previously had
some issues with IPv6 during testing as well as updated some of the
tests to use `retry` over `check`.
As discussed this adds handling to timeout at a max of 500ms for fetch
cache request and retries a max of 3 times due to network instability.
This also adds cache service tests and fixes a case we've been trying to
track down where we were seeing `undefined` cache URL values which made
debugging fetches tricky.
To assist with the development and testing of the new partial
prerendering (PPR) paradigm, this introduces a stop-gap solution to let
us verify issues with pages in preview and production environments if
enabled. When a Next.js app is built and ran with the
`__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING=1` environment variable,
pages that have PPR enabled in production and preview environments can
have only their static shell served when accessed with a
`?__nextppronly=1` query parameter.
If your project is not using PPR, it will not change anything. If a page
is accessed in production or development with the query parameter but
PPR is not enabled, it will not change anything. Tests have been added
to validate that going forward.
### What
Optimizing the static generation for dynamic metadata routes
If you're not using `generateSitemaps()` or `generateSitemaps()`, you
don't need to change any file conventions.
If you're using multi sitemap routes, make sure the returned `id`
properties from `generateSitemaps()` don't need to contain `.xml`, since
we'll always append one for you.
Analyzing the exports of metadata routes and determine if we need to
make them as dynamic routes.
### Why
Previously, users are struggling with the multi routes of sitemap or
images.
For sitemap, the `.xml` extension in url doesn't get appended
consistently to the multi sitemap route between dev and prod.
For image routes, the generated image routes are always dynamic routes
which cannot get static optimized.
The reason is that we need to always generate a catch-all route (such as
`/icon/[[...id]]` to handle both single route case (e.g. without
`generateImageMetadata`, representing url `/icon`) or multi route (e.g.
with `generateImageMetadata`, representing url `/icon/[id]`), only
catch-all routes can do it. This approach fail the static optimization
and make mapping url pretty difficult as parsing the file to check the
module exports has to be done before it.
#### Benifits
For image routes urls, this approach could help on static generation
such as single `/opengraph-image` route can be treated as static, and
then it can get static optimized if possible.
**Before**: `/opengraph-image/[[...id]]` cannot be optimized
**After**: single route `/opengraph-image` and multi-route
`/opengraph-image/[id]` are both possible to be statically optimized
For sitemap, since we removed appending `.xml` for dynamic routes, it’s
hard for users to have `/sitemap.xml` url with dynamic route convention
`sitemap.js` . But users desire smooth migration and flexibility.
**Before**: In v15 rc we removed the `.xml` appending that `sitemap.js`
will generate url `/sitemap` makes users hard to migrate, as users need
to re-submit the new sitemap url.
**After**: Now we'll consistently generate the `.xml`. Single route will
become `/sitemap.xml`, and multi route will become `/sitemap/[id].xml`.
It's still better than v15 as the urls generation is consistent, no
difference between dev and prod.
Here's the url generation comparsion
#### Before
All the routes are dynamic which cannot be optimized, we only had a
hacky optimization for prodution build multi-routes sitemap routes
| | only default export | `export generateImageMetadata()` | `export
generateSitemaps()` |
| -- | -- | -- | -- |
| opengraph-image.js | /opengraph-image/[[...id]] |
/opengraph-image[[...id]]/ | /opengraph-image/[[...id]] |
| sitemap.js | /sitemap/[[...id]] | /sitemap/[[...id]] | dev:
`/sitemap/[[...id]]` prod: `/sitemap/[id]` |
#### After
Most of the single route will are to get statically optimized now, and
the multi-routes sitemap are able to get SSG now
| | only default export | `export generateImageMetadata()` | `export
generateSitemaps()` |
| -- | -- | -- | -- |
| opengraph-image.js | /opengraph-image | /opengraph-image/[id] | - |
| sitemap.js | /sitemap.xml | - | /sitemap/[id].xml |
Next.js will have less overhead of mapping urls, we can easily multiply
the urls generation simply based on file conventions.
x-ref: feedback from #65507Closes#66232
### Why?
Importing `tailwind/tailwind.css` is not possible right now with
turbopack, and there's no reason it needs to be marked as external.
### How?
Closes PACK-3013
Fixes#64837
### What
Keep `test/e2e/app-dir/metadata-dynamic-routes/index.test.ts` with
successful build cases, move the dev error tests into separate test
### Why
x-ref:
https://github.com/vercel/next.js/actions/runs/9429301722/job/25975574075?pr=66286
Before the moving the tests, the error is flaky with turbopack since the
error will fail the hmr. Error observed with turbopack when seeing build
failed cases. So I moved the tests into the separate dev tests, running
inside sandboxes. Then each error test doesn't effect each other.
```
⨯ ./app/metadata-base/unset/icon--metadata.js:1:1
Module not found: Can't resolve './icon.tsx'
> 1 | import { generateImageMetadata } from "./icon.tsx"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | import { fillMetadataSegment } from 'next/dist/lib/metadata/get-metadata-route'
3 |
4 | const imageModule = { generateImageMetadata }
```
### What
Remove creating client proxy for each ESM export, instead for ESM we
create a CJS module proxy for itself and access the property with export
name as the actual export.
### Why
`proxy` is the module proxy that we treat the module as a client
boundary.
For ESM, we access the property of the module proxy directly for each
export.
This is bit hacky that treating using a CJS like module proxy for ESM's
exports,
but this will avoid creating nested proxies for each export. It will be
improved in the future.
Notice that for `next/dynamic`, if you're doing a dynamic import of
client component in server component, and trying to access the named
export directly, it will error. Instead you need to align the dynamic
import resolved value wrapping with a `default:` property (e.g. `{
default: resolved }`) like what `React.lazy` accepted.
Revert #57301Fixes#66212
x-ref:
[slack](https://vercel.slack.com/archives/C04DUD7EB1B/p1716897764858829)
During navigations, the `FlightDataPath` property from the server
response can be an array if there are multiple parallel routes (eg,
`children` and `slot`). When we apply server response to the router
cache, we might call `applyFlightData` for each segment path, which will
copy existing cache values and insert new ones depending on what
changed.
However, the `existingCache` argument that we pass to this function is
the cache at the start of the navigation. That means subsequent calls to
`applyFlightData` will reference the cache _before_ updates are made to
it. This will cause it to erroneously think it needs to lazy fetch for
missing data.
<!-- 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 #
-->
When checking which segment(s) need to be refreshed, we currently
compare the current page URL with the segment's refresh marker.
We should inspect the `mutable.canonicalUrl` value first since that's
the URL we're changing to, followed by `state.canonicalUrl` as a
fallback (indicating that there's no URL change pending). This is
because the server action handler will receive a redirect URL prior to
`location.pathname` being updated, so the router will incorrectly think
it needs to refresh the data for the page we're going to.
Closes NEXT-3500
This flag remained experimental because the IPC implementation didn't
play nicely with requests containing large payloads, due to it being
stringified as GET parameters. This branching logic also poses
challenges for some upcoming work related to detecting IO.
This removes the handling for the
`experimental.staticWorkerRequestDeduping` flag which we can revisit in
the future with a sounder approach. This also cleans up some of the IPC
server utilities as it wasn't in use anywhere else.
<!-- 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 & Why
Fixes NEXT-3498
Fixed loading shows up and disappear during client navigation, when you
defined `prefetch` is enabled and slow `generateMetadata` is defined. In
#64532, where in layout-router, we removed the place of infinite
suspense, adding it back so that the app can still remain suspensy
during navigation.
#### Behavior before fix
Prefetch -> Link Navigation -> Show `loading.js` -> RSC payload fetched
(no page content) -> the page content will display later when the
promise is resolved
#### Behavior after the fix
Prefetch -> Link Navigation -> Show `loading.js` -> RSC payload fetched
-> suspensy page content still triggering `loading.js` -> display the
resolved page content when the promise is resolved
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
When `router.refresh` or a server action creates a new `CacheNode` tree,
we were erroneously not copying over the `loading` segment in the new
tree. This would cause the subtree to be remounted as the loading
segment switched from having a Suspense boundary to not having one.
Fixes#66029Fixes#66499
This removes the previous `server/future` directory and moves everything
into the `server` or `server/lib` directories. This is aimed to start to
flatten the server application structure.
### What?
* order of CSS between layout and page
* order of CSS between page and next/dynamic
### Why?
### How?
* overrides webpack CSS chunk loading to use react CSS loading to allow
them to share the order
This takes the `layerAssets` property from the previous PR and actually
renders it, replacing the previous style handling. This ensures that
when multiple page segments are rendered on screen, all of their
associated CSS files are loaded. The existing `findHeadInCache` method
only ever returns a single head node, which means it’d miss stylesheets.
Fixes#59308Fixes#63465
This adds details for every ISR cache request if the page being
requested supports PPR. If it does, it'll attempt to load the
`.prefetch.rsc` payload instead of the `.rsc` payload. This corrects a
bug that was present in deployed environments.
This additionally refactors the `isAppPPREnabled` out of most of the
application, as it's only used to determine if we should add to the
`prefetchDataRoute` fields in the `prerender-manifest.json`. To support
loading the prefetch file or not, we pass the `isRoutePPREnabled`
through with the cache get/set operations instead.
x-slack-ref:
https://vercel.slack.com/archives/C075MSFK9ML/p1717094328986429
In #60645, dynamic access tracking was refactored but we erroneously
stopped tracking dynamic access in route handlers. Request proxying, as
well as tracking segment level configs (such as `export const dynamic =
'force-dynamic'`), were only enabled during static generation. This was
an unintended breaking change that consequently caused dynamic access to
not properly bail from data cache in various circumstances.
This adds some more rigorous testing for route handlers, as this seems
to be a fairly large gap in our fetch cache testing currently.
This PR is easiest to review with [whitespace
disabled](https://github.com/vercel/next.js/pull/66446/files?w=1).
### What
Change the metadataBase missing warning for all cases to only warn in
standalone mode or the non-vercel deployment.
### Why
In vercel deployments, previous concern was that you might not discover
you missed that metadataBase when you deploy. But now we have sth
fallback on production deployments. So we only need to warn in
non-vercel deployment.
Standalone is usually for self-hoist, we always warn users to set the
`metadataBase` to make sure the domain can be properly resolved.
[x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1716926825853389?thread_ts=1716923373.484329&cid=C03S8ED1DKM)
When the router encounters a `stale` cache entry, it clears the `rsc`
data so that it can be fetched in render. All navigations (even just for
hash fragments) flow through the navigation reducer, which has logic to
discard any existing cache entries when the cache is stale.
This bug has become more obvious after removing the default 30s cache,
which would previously have masked it.
This updates the existing handling that clears flight data to not do so
if only the hash changes as there would be no server changes in this
case.
<!-- 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 #
-->
Transient/recoverable errors can cause page(s) to fail. When building an
app with a lot of static pages, a single page failing to build can be
frustrating, especially if it it'll pass on a retry. This adds an
experimental `staticPageGenerationTimeout` property that can be used to
configure how many times Next.js attempts to build a particular page
before giving up.
I recommend reviewing this PR [without
whitespace](https://github.com/vercel/next.js/pull/66393/files?w=1)
<!-- 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 #
-->
This modifies the patched fetch implementation to better handle when
called within an `unstable_cache` callback. In these callbacks, it
should not throw an error related to dynamic access.
This replaces the verbose `trackDynamicFetch` instead with
`markCurrentScopeAsDynamic` which already has support for checking if
inside an unstable cache context. It also has been adjusted to be a
no-op when `export const dynamic = "force-static"`, further simplifying
the code within the patch fetch implementation.
### What
Use `next-flight-loader` to transform the client components into client
reference in middleware and instrumentation.
Add related required webpack aliases, such as alias for
`react-server-dom-webpack`
### Why
issue reported in
https://github.com/vercel/next.js/pull/65424#issuecomment-2128902585
### What?
Because `createMultiHtmlMatcher` does not use `await` keyword internally
and is not an async function, all `await` in front of the match function
returned from `createMultiHtmlMatcher` was removed in
`test/e2e/app-dir/metadata/metadata.test.ts`.
The JSDoc for `createMultiHtmlMatcher` was also modified.
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
This allows us to set breakpoints and debug e2e tests without
encountering a timeout after 60 seconds. For example, using:
```
NEXT_E2E_TEST_TIMEOUT=1000000 NODE_OPTIONS=--inspect-brk pnpm test-dev test/e2e/app-dir/metadata/metadata.test.ts
```
Notably, this change also affects the turbopack dev tests in the CI,
where `NEXT_E2E_TEST_TIMEOUT` is currently set to 240 seconds. Since the
same env variable is also used for `jest.setTimeout()`, a test timeout
will now most likely occur due to jest timing out, and not a specific
playwright check (i.e. `waitForElementByCss` or `waitForCondition`)
timing out. This sounds acceptable to me.
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Using the hostname `::` enables dual-stack support. This prevents
`ECONNREFUSED` errors when running tests locally, and `localhost` being
resolved to `::1` (IPv6) instead of `127.0.0.1` (IPv4).
During integration testing, previously, calls to `next build` could rely
on the project (the Next.js project) level ESLint configuration. In
order to correct this, a new `lint` option was added to `nextBuild` that
can be passed to enabled linting. If this is `false` or `undefined`, a
`--no-lint` argument will be passed to `next build` to prevent it from
running.
Old logic from the pages router was previously being hit during
development. This was more apparent when PPR was enabled as it was
mixing dynamic + static rendering in development which propagated to
errors. This change ensures that requests that are made with `RSC: 1`
are not marked as `/_next/data` URL's, and don't use the same logic
paths.
Previously it was a bit confusing because we used the variable
`isDataReq` in a few places that made it hard to tell what it was
referring to. In this case, the `isDataReq` is actually only used by the
pages router. This renames the `isDataReq` to `isNextDataRequest` to
make it clearer, as well as refactors to ensure that it's not used in
the paths for app routes.
Also to better represent the rendering modes the `supportsDynamicHTML`
variable was renamed to `supportsDynamicResponse`.
Fixes#66241
Revert the revert in #66049
It was erroring in pages api with importing `react-dom/server` as this
is disallowed in app but shouldn't be in pages. It's caused by we're
validating middleware layer as server components but edge pages api is
still bundled in the same layer, where we shouldn't apply the check.
* Separate the api in api layers, and while handling middleware
warnings, checking api layer as well
* No need to check layers while handling externals in edge compiler
* Found a bug that we shouldn't check if `config.transpilePackages` is
defined then we enable `externalDir`, removed that condition. It fails
the telemetry tests case build with code change from this PR.
Add more tests for pages dir and middleware
| | `react` condition | `react-dom/server` condition |
| ---- | ---- | ---- |
| middleware (edge) | react-server | not allowed, failed with dev/build
checks |
| pages/api edge | default condition | default condition |
| pages/api node | default condition | default condition |
This reverts commit
637033c410.
What wasn't clear originally is that we require that required packages
have their `package.json` resolvable. So either they don't have an
`exports` field, or their `package.json` is listed in the `exports`
field. The React beta types didn't have `package.json` entry in
`exports` so we accidentally thought they weren't installed.
I published [`19.0.0-beta.2` that has `package.json` in
`exports`](13879ee571 (diff-81cc573aa0c2bd0e13f9463499747741704aabccd7474f544db710befd7bcfc4R44))
so we can restore the old behavior. It's still questionable IMO to do
all that I/O work just for a nicer error message that may contain
false-positive but that's for another time.
This PR changes the `getWaitUntil` logic to always check if the platform
provided a request context with a `waitUntil` implementation (via [the
`@next/request-context`
symbol](05e6b82576/packages/next/src/server/after/wait-until-builtin.ts (L12)))
, regardless of minimalMode or runtime.
Previously, we wouldn't check the context at all unless `minimalMode`
was set, and defaulted `waitUntil` to a noop otherwise. This would make
integration more difficult for providers who don't use `minimalMode`,
because they'd have no way to inject their `waitUntil` implementation.
Ensures that app routes (like the `favicon.ico` added in the test case
in this PR which is represented as an app route) do not have a prefetch
RSC also attached.
## Background
Previously we introduced automatic caching for `fetch` based on certain
heuristics that were a bit tricky to grasp all scenarios. The scenarios
we would automatically cache were no dynamic data access before the
fetch call e.g. `headers()` or `cookies()`, the fetch call is inside of
a dynamic page e.g. `POST` method or `export const revalidate = 0` page
and the fetch is a non-`GET` request or has `Authorization` or `Cookie`
headers, or the fetch had `cache: 'no-store' | 'no-cache'` or
`revalidate: 0`.
## New Behavior
By default fetches will no longer automatically be cached. Instead they
need to be opted-in to caching via `export const fetchCache =
'default-cache' | 'force-cache',` `next: { revalidate: false or value >
0 }` or `cache: 'force-cache' | 'default-cache'`.
When the fetch call is automatically skipping the cache it won't impact
the page level ISR cacheability although if a fetch call manually
specifies `cache: 'no-store'` or `revalidate: 0` it will still bail from
the page being statically generated as it was before.
To achieve the previous behavior of automatic fetch caching all that
needs to be added is `export const fetchCache = 'default-cache'` in the
root layout(s) of your project.
Follow-up to https://github.com/vercel/next.js/pull/65825 this ensures
we don't skip the static optimization specifically for metadata routes
as this most often should be static as they aren't dynamic content and
are requested very frequently.
This configures the default client router cache `staleTime.dynamic`
value to be `0`.
This means that:
- Navigating between pages will always fire off a network request to get
RSC data for the page segment, rather than restoring from router cache
- Loading states will remain cached for 5 minutes (or whatever
`config.experimental.staleTimes.static` is set to)
- Shared layout data will continue to remain cached due to [partial
rendering](https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#4-partial-rendering)
- Back/forward behavior will still restore from cache to ensure the
browser can restore scroll position.
It's possible to opt-out of this, and into the previous behavior, by
setting the
[`staleTimes`](https://nextjs.org/docs/app/api-reference/next-config-js/staleTimes)
config in `next.config.js`:
```js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30
},
},
}
module.exports = nextConfig
```
<!-- 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 #
-->
This reverts the below changes to avoid a breaking change in pages with
importing `react-dom/server` as this is disallowed in `app` but
shouldn't be in `pages`.
Revert "Bundle the installed react for middleware (#65811)"
Revert "Error in build for middleware when import client-only (#65792)"
This reverts commit fdd8f0c65f.
This reverts commit 082072ca95.
x-ref: [slack
thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1716305493514869)
Noticed while testing turbopack version of tests that we weren't loading
the correct swc binary since this path wasn't absolute and was just the
relative path in `node_modules`.
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
Since, https://github.com/vercel/next.js/pull/65830, I've been seeing
weird flakes from
`test/e2e/app-dir/app-invalid-revalidate/app-invalid-revalidate.test.ts`.
```
TIMED OUT: /Invalid revalidate value "1" on "\/", must be a non-negative number or "false"/
```
The build output looks like this:
```
▲ Next.js 14.3.0-canary.73
Creating an optimized production build ...
[snip]
Error: Invalid revalidate value "1" on "/_not-found", must be a non-negative number or "false"
[snip]
Generating static pages (2/4)
> Build error occurred
Error: Export encountered an error on /_not-found, exiting due to prerenderEarlyExit: true being set
```
Note that there's no `Invalid revalidate value "1"` message for `/`, so
the test will fail.
This looks like a race condition: the invalid `revalidate` value is set
in a layout, so if `_not-found` happens to be prerendered before `/`,
it'll abort the whole prerender (because of `prerenderEarlyExit: true`).
so if the timing is right, the test -- which is looking for build errors
for `/` -- will never see them and time out.
There might be more of these, but unfortunately they're basically race
conditions, so I think we'll have to squash them as they come up.
CC @ijjk
## Background
Currently route handlers will be attempted to statically generate the
same as normal pages in app router. If a route handler accessed dynamic
data such as `cookies()`, `headers()`, `req.url`, or similar we would
bail from this static generation but this didn't handle the case where
you would do data fetching via a non-fetch based library e.g. `redis` or
even using `Date.now()` or `Math.random()` so users would expect these
to be run every request like normal API endpoints but they would be
static so wouldn't be executed again after a build.
## New Behavior
As discussed this disable the default static generation handling for
route handlers as we've seen this confuse our users since in most cases
when creating a route handler you are handling dynamic workloads. This
doesn't remove the ability to static generate route handlers though as
you can still manually specify:
If you specify `export const revalidate = 1` we will still bail if
dynamic data is accessed to prevent accidental `revalidate` configuring
but this can be avoided via `force-static` being used as well.
```js
export const dynamic = 'force-static'
// or
export const dynamic = 'error'
// or
export const revalidate = false
// or
export const revalidate = 1 // value great than 0
// or
export const generateStaticParams() {}
```
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
This PR addresses an issue where the `dev` script in `package.json` was
not correctly updated to use the `--turbo` option when specified. The
changes ensure that the `dev` script is set to `next dev --turbo` if the
`turbo` option is enabled.
### Changes:
1. **Function Modification**:
- Updated the `modifyPackageJson` function to include a check for the
`turbo` parameter.
- If `turbo` is true, the `dev` script in `package.json` is set to `next
dev --turbo`.
- If `turbo` is false, the `dev` script remains `next dev`.
2. **Integration in App Creation**:
- Integrated the `modifyPackageJson` function into the app creation
process to ensure the `dev` script is correctly set based on the `turbo`
parameter.
### Testing:
- Verified that the `dev` script in `package.json` is correctly updated
to `next dev --turbo` when the `turbo` option is enabled.
- Ensured that the `dev` script remains `next dev` when the `turbo`
option is not enabled.
### Related Issues:
- Fixes#65924
### Notes:
- This change ensures that developers opting to use Turbopack for
development will have the correct script set up automatically.
---------
Signed-off-by: Arindam Majumder <arindammajumder2020@gmail.com>
Co-authored-by: Lee Robinson <me@leerob.io>
Co-authored-by: devjiwonchoi <devjiwonchoi@gmail.com>
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
Co-authored-by: Sam Ko <sam@vercel.com>
Currently `OPTIONS` requests to page handlers (eg `pages/foo.tsx` or
`app/foo/page.tsx`) will respond as though it's handling a `GET`
request. There should be no reason for these routes to handle `OPTIONS`
requests as the only valid option is `GET`.
We do not need to special-case actions here because those will always be
invoked from the same origin as the canonical browser 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-3305
## Background
Historically during prerendering we have waiting until all paths have
been attempted before we exit the process and fail the build. This is
nice if you want to collect all potential errors to address them at the
same time although this has the drawback of slowing down builds if
things are timing out or if the same error is occurring across numerous
paths.
## New Behavior
This changes our default behavior to immediately exit when the first
error occurs during prerendering so that builds don't stall out from
timeout errors or from the same error occurring across numerous paths.
This will help from holding up CI or similar un-necessarily.
If users want to opt-in to the previous behavior the flag is still
present under `experimental.prerenderEarlyExit`.
cc @icyJoseph @ztanner
NOTE: The canary release
[`v14.1.1-canary.51`](https://github.com/vercel/next.js/releases/tag/v14.1.1-canary.51)
and below work as expected.
### Why?
Introduced from #61535, the initial prefetch cache is set based on the
`location.pathname`.
When a page is loaded WITH the search param, the cache key does not
contain information of the search param.
The issue is when on a dynamic page reading the `searchParams` value,
the value doesn't change if navigated as:
```
/?q=foo --> /
```
The prefetch cache hits, not re-rendering, and the `searchParams` value
is not passed properly.
### How?
For the prefetch cache, add the `location.search` as well.
Since `createPrefetchCacheKey` uses
[`createHrefFromUrl`](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/router-reducer/create-href-from-url.ts)
which includes `location.search`, I'm expecting the change won't affect
current cache key behavior.
Fixes#64170Fixes#65030
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
Adds support for nested `unstable_after()`.
This pattern previously threw a "Not supported yet" error, but works
now:
```js
function MyComponent() {
after(() => asyncWork());
return <div>...</div>
}
async function asyncWork() {
after(() => { /* look ma, nesting!*/ })
// more stuff...
}
```
### Implementation notes
Switched `AfterContext` to use a proper promise queue
([`p-queue`](https://www.npmjs.com/package/p-queue)) instead of plain a
callback array to support adding more callbacks as we execute (i.e. from
nested `after`s). Used a package because I didn't want to reinvent the
wheel here.
As a nice bonus, `p-queue` lets us limit the concurrency of running
tasks if we're worried about resource consumption. **This PR doesn't do
that**, but it's very easy to add. That could be controlled via
`process.env.NEXT_AFTER_MAX_CONCURRENT_TASKS`, a next.config.js option
(`unstable_after: { maxConcurrentTasks: 5 }`), or something like that.
### What?
Upgrades sharp to the latest version and relies on more of its default
settings (if the default settings are unsuitable, we should consider
improving these for all users in sharp itself).
- The `sequentialRead` setting is now managed for you based on each
input image and the operations to be applied to it.
- The concurrency detection is more accurate than `os.cpus()` as it now
inspects things like CPU set/affinity as well as the memory allocator.
- The (mostly archaic) concept of chroma subsampling is not required for
AVIF output. Using full chroma should improve the quality of red/orange
edges, as well as slightly reducing file size as it allows greater use
of AV1 chroma-from-luma prediction.
In addition, this PR also enables the use of mozjpeg features such as
trellis quantisation to produce smaller file sizes. The use of `mozjpeg:
true` infers `progressive: true`. This aligns JPEG output behaviour with
the previously-used squoosh, which always used mozjpeg.
/cc @styfle