> [!TIP]
> Recommended to review commit by commit.
This PR adds `next upgrade --experimental-ai="security"` flag (alias
`--ai`), which is targeted to help users leverage agents to upgrade
their app to the safe major version when their app's Next.js version has
any security advisories.
Once the command is ran from the user, Next.js will detect the installed
agent harness in user's device, currently limited to Codex and Claude,
and will proceed with starting an agent session once approved. If it is
called within an agent session, the work will continue off within that
agent.
`next upgrade --ai` simply does two things:
- prepare the relevant context to temporary dir
- print hand off prompt, guiding to read those context
The context will guide the agent to run relevant codemods and migration
checklist to proceed. This PR is a base core of the workflow, and will
have wrappers of entry point around this. Also, will add "latest" and
"future" as follow up, which will cover the app to be always latest, and
adopt the future defaults like Cache Components.
This PR also sets up the evals infra and adds evals.
Extract the instant navigation testing API into a standalone
@next/playwright package. The instant() helper lets Playwright tests
assert on prefetched/cached UI by deferring dynamic data during
navigations — similar to throttling the network in DevTools.
The package is private: true for now. The goal is to get the scaffolding
ready so we can flip it to public when the API is ready to ship.
The existing inline implementation in the instant navigation test file
is replaced with an import from @next/playwright. The nested scope test
now exercises actual nested instant() calls rather than manipulating the
cookie directly.
The protocol is intentionally minimal (a single cookie) so that other
testing frameworks and dev tools can replicate the behavior with minimal
effort.
The file already had the `@ts-check` directive, so the IDE did show errors in that file. But since it was not included in the root `tsconfig.json`, those errors were not reported during CI runs.
One issue found this way was that the `related` flag was defined but never used. The referenced script was removed in #67644.
Same basic idea as https://github.com/vercel/next.js/pull/78787
This test suite has a lot of timeouts with rspack, which causes it to take a long time to run (though not quite long enough that it breaks the job).
In general, large test suites are good to break up, because they benefit from parallelism.
---
In addition to breaking this test suite up, I also ported it to the new framework, as the way it was patching `next.config.js` was causing problems, since the old integration tests are not run in isolated directories.
With this PR, we're changing the experimental cache handler interface that's used for `"use cache"` cache handlers:
- A new method `refreshTags(): Promise<void>` has been added.
- Next.js will call this function periodically, but always before starting a new request. When working with a remote tags service, this method should communicate with the tags service to refresh the local tags manifest accordingly.
- A new method `getExpiration(...tags: string[]): Promise<Timestamp>` has been added.
- Next.js will call this function for each set of soft tags that are relevant at the start of a request. The result is the maximum timestamp of a revalidate event for the tags.
- The `get` method does not accept the soft tags anymore as its second arg: `get(cacheKey: string): Promise<undefined | CacheEntry>`
- Checking the expiration of a cache entry via soft tags is now handled by Next.js.
- The `receiveExpiredTags` method has been removed.
- This was used for two things:
1. Refreshing the tags in the tags manifest. This was replaced by `refreshTags`.
2. Setting the passed-in tags as expired in the tags manifest. This was used for redirecting server actions. Discarding cache entries based on these tags is now handled by Next.js internally.
To ease migration, the previous cache handler interface is still supported for now.
closes NAR-110
This work introduces the new concept of **Partial Fallback Prerendering
(PFPR)**.
Traditionally, when a dynamic page needed to be routed to that wasn't
pregenerated, it required a render to generate even the first few bytes
of the static page itself. This resulted in slow page loads for pages
not frequently visited and a reduced Time to First Byte (TTFB) score on
Core Web Vitals (CWV).
PFPR takes advantage of the new systems of Partial Prerendering (PPR)
that allows the application to suspend at different points mid-render,
and resume it later. We mark any unknown parameter access as dynamic
access, and suspend the rendering up to the next suspense boundaries at
those points. Under ideal conditions (correctly placed `<Suspense />`
boundaries or `loading.jsx` files) this generates a static shell that
can be served to users as soon as the request hits Next.js, right out of
the static cache. This minimizes the TTFB for all requests, dynamic or
not for those pages that enable PPR. For example, the following page
would create a usable shell:
```jsx
// /app/users/[userID]/page.jsx
import { Suspense } from 'react'
function Profile({ params }) {
const { userID } = params
return <div>Hello {userID}!</div>
}
export default function ProfilePage({ params }) {
return (
<div>
<h1>User Profile</h1>
<Suspense fallback="Loading...">
<Profile params={params} />
</Suspense>
</div>
)
}
```
Due to the way that suspense works within React components, access of
params within the root page component would cause the whole page to
suspend. Thankfully, that's where the `loading.jsx` comes in handy.
Adding a `loading.jsx` at a segment will automatically wrap the
`page.jsx` with a suspense boundary, setting the contents of the root
`loading.jsx` as the fallback component to use for it. This lets you
maintain your existing style of accessing parameters at the root of the
components while also taking advantage of PFPR.
To enable this feature, you first need to enable both PPR and PFPR:
```js
module.exports = {
experimental: {
ppr: true,
pprFallbacks: true,
}
}
```
Once PFPR has stabilized with hosting providers, the experimental flag
will go away and it will become the default with the PPR flag.
- Include test files when type checking `packages/font`, while still excluding them in `build`.
- Include `turbo/generators` files in root `tsconfig.json` so that they are type checked as well.
You'll probably want to disable whitespace in the diff
## Description
This allows for better editor support by using `describe` or functions called `describe` with the same syntax instead of custom names.
Changes:
- `nextTestSetup` can be used instead of `createNextDescribe` keeping the same behaviour but being called inside a `describe` "block" (not applied everywhere)
- `getSnapshotTestDescribe` replaced with a custom `describe.each`
- `sandbox` helper function for `acceptance`/`acceptance-app` merged into a single shared one
- `outdent` to remove the indent from inline files in tests which helps with consistent snapshots
Update workspace cargo deps
Update cargo deps to point to local workspace
Ignore too-many-arguments warnings
Fix clippy errors
Update pnpm workspaces
exclude integration tests from unit tests CI
rust-analyzer settings
add rust flags and env vars
* Adds tests to ensure `eslint-plugin-next`'s available rules are properly exported and recommended rules are defined correctly.
* Condenses imports.
* Sets default recommended value.
* replace Object.hasOwn for node 14
Co-authored-by: JJ Kasper <jj@jjsweb.site>
* Move unit tests to one folder
* Migrate unit tests to TypeScript
* add test types to lint
* Ensure ts(x) tests are run with util
* Add tsx extension to jest config
* bump