Commit Graph

41 Commits

Author SHA1 Message Date
Jiwon Choi b0ba92cbc6 Unify TODO markers for codemods and skip adoption-only codemods for upgrade (#98560)
### Why?

Async Request API codemods can leave temporary casts that still require
application-specific repairs. Those locations need explicit markers,
while optional feature adoption needs to be distinguishable from
required version migrations.

### How?

Add `@next-codemod-error` comments to temporary `UnsafeUnwrapped*`
casts, with instructions for completing the repair. Preserve documented
ignores and avoid duplicating casts or markers when the transform runs
again. Mark generated Cache Components opt-outs with
`@next-codemod-ignore`, a removal condition and a link to the adoption
guide.

Add `upgrade --skip-adoption` to skip the Cache Components `instant =
false` transform and partial-prefetch adoption cleanup. Required
migrations and normal dependency and bundler selection keep their
existing behavior. Both adoption transforms can still be run explicitly.
2026-09-14 12:36:33 +02:00
Aurora Scharff 420ab0c7e1 docs: add route-side URL data audit to the Partial Prefetching adoption guide (#95389)
## What

Follow-up to #95365. Documents adopting Partial Prefetching end to end:

- Restructures the [Adopting Partial Prefetching
guide](https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/adopting-partial-prefetching.mdx)
around the two paths: enable `partialPrefetching` and audit every `<Link
prefetch={true}>` against a per-case decision table, or adopt
incrementally per route with the
[`instant-link-prefetch-partial`](https://nextjs.org/docs/messages/instant-link-prefetch-partial)
insight as the worklist. Adds `Auditing routes for URL data` and
`Prefetching URL data` sections.
- Adds the `remove-partial-prefetch` codemod, which strips the redundant
per-route `prefetch = 'partial'` exports once the flag is on while
preserving comments and other `prefetch` values.
- Adds the `next-partial-prefetching-adoption` skill that sequences the
guide for agents: audit, enable + codemod, URL-data sweep, verify,
optional runtime prefetching.
- Aligns the `instant-link-prefetch-partial` error page, `<Link>`
reference, glossary, and Interactive apps guide with the same prefetch
model.

## Why

With the flag on, `<Link prefetch={true}>` no longer delivers dynamic
content, and shell validation flags `params`/`searchParams` reads
outside `<Suspense>`. Adopters need one guide that sequences the audit,
the flag, and both insights, and an agent skill that follows it.

Stacked on #95365 (base: `codex/instant-shell-link-data`) since it links
to the `instant-shell-url-data` error page that PR introduces. GitHub
will retarget to `canary` when that merges.

<!-- NEXT_JS_LLM_PR -->
2026-07-14 20:22:00 +02:00
Aurora Scharff ae62a6f79b codemod: cache-components-instant-false + next-cache-components-adoption skill (#94941)
### Why?

Turning on `cacheComponents` makes every blocking route a build error at
once. On a large app that's a wall of failures with no clear order to
fix them in, which is a rough first experience.

### What?

An opt-in adoption path so enabling Cache Components doesn't have to be
all-or-nothing:

- **`cache-components-instant-false` codemod** (`@next/codemod`) —
blanket-inserts `export const instant = false` (with a `// TODO: Cache
Components adoption` comment) into every `app/**/{page,layout}` file, so
the build goes green immediately. Idempotent: skips files that already
export `instant` (including aliased `export { x as instant }`). Skips
Client Components (`"use client"`) and route handlers.
- **`next-cache-components-adoption` skill** (`skills/`) — sequences the
full migration in five steps across four milestones: green build
(codemod or direct), remove the opt-outs top-down one group at a time,
make navigations instant via the dev-overlay Insights, then adopt
Partial Prefetching. It defers individual fixes to the dev overlay fix
cards, stack traces, and the `/docs/messages/blocking-prerender-*`
pages, and points at the migration / instant-navigation / Partial
Prefetching guides rather than re-teaching them. Verifies each change at
runtime via `next-dev-loop` (with a manual dev-overlay fallback). The
`next-cache-components-optimizer` skill is referenced only as optional
shell-growing polish after adoption is complete.

### How?

- Transform registered in `TRANSFORMER_INQUIRER_CHOICES` at `version:
'16.3.0'`.
- 8 fixtures cover insert-into-page / -layout, JSDoc placement, and
no-op on existing / aliased / multi-declarator / local-binding `instant`
and on `"use client"` pages. `pnpm jest cache-components-instant-false`
passes.
- Docs: a `cache-components-instant-false` entry in the codemods
reference, and a pointer to the skill + codemod from the migration
guide.
2026-06-22 20:52:16 +02:00
Jiwon Choi 3f854dc3ea [codemod] fix: next-lint-to-eslint-cli did not handle 'next' plugin (#85749)
Codemod `next-lint-to-eslint-cli` did not handle `extends: ['next']` in
legacy ESLint config.

x-ref:
https://github.com/vercel/next.js/issues/85244#issuecomment-3482558412

Fixes #85244
2025-11-03 23:18:27 +01:00
Jiwon Choi e8685ebc12 [codemod] Install ESLint v9 if version under for next-lint-to-eslint-cli (#85182)
When running `next-lint-to-eslint-cli` and ESLint version lower than 9,
upgrade to `^9` to ensure full Flat config support.
2025-10-21 14:48:58 -07:00
Jiwon Choi 0295842b7b Update next-lint-to-eslint-cli to support FlatCompat.config (#85026)
ESLint `FlatCompat` can be used in two ways:

```js
compat.extends('next/core-web-vitals', 'next/typescript')
```

```js
compat.config({
  extends: ['next/core-web-vitals', 'next/typescript'],
})
```

Although using `.extends()` is recommended for migration, and the ESLint
migration tool also uses that, it is possible to use `.config()`, so
handle them as well for the migration.

Confirmed on local apps as well.
2025-10-18 22:45:56 +02:00
Jiwon Choi b42555aa39 Add codemod for removing experimental_ppr (#84979)
`experimental_ppr` is removed by
https://github.com/vercel/next.js/pull/84871, so add codemod for it.
2025-10-17 03:45:02 +02:00
Jiwon Choi 6bd5c47b90 Add codemod for removing unstable_ prefix (#84974)
Stacked on https://github.com/vercel/next.js/pull/84877,
https://github.com/vercel/next.js/pull/84880

This PR adds a codemod for removing the `unstable_` prefix for
stabilized APIs. It is considered to scale by adding more APIs to the
`UNSTABLE_TO_STABLE_MAPPING` map in the future to this codemod.

Closes NEXT-4739
2025-10-17 00:55:30 +02:00
Jiwon Choi e9a8ee5040 Update codemod ESLint template to Flat config (#84919)
Stacked on https://github.com/vercel/next.js/pull/84874

### Why?

As `eslint-config-next` supports Flat config since PR
https://github.com/vercel/next.js/pull/84874, Release
[v16.0.0-canary.6](https://github.com/vercel/next.js/releases/tag/v16.0.0-canary.6),
update codemod to use Flat config. Since `eslint-config-next` version
and this codemod's version will match, no need to gate the version, as
by the time this change is released, the same `eslint-config-next`
version will support Flat config.

### How?

Updated to handle the three cases:

- Legacy config
- Flat config with FlatCompat (Which we used to recommend for v15)
- Flat config with no FlatCompat (Which means the app does not use
`eslint-config-next`)

For the Legacy config, ESLint provides a [Migration
tool](https://eslint.org/docs/latest/use/configure/migration-guide), so
use that to convert to Flat config. It will include FlatCompat, so the
rest of the process is the same as Flat config with FlatCompat.

For the Flat config with FlatCompat, the codemod will remove FlatCompat
and map the `eslint-config-next` imports directly to the export.

For the Flat config with no FlatCompat, the codemod will import
`eslint-config-next` and map the imports directly to the export.

Tested on
[shadcn/ui](https://github.com/shadcn-ui/ui/blob/cb769b7059b50b5dca033a6eb57bb8ecde69fc87/.eslintrc.json)
and other large legacy ESLint configs.
2025-10-16 19:08:34 +02:00
Jiwon Choi e42c7cf70e Add codemod for middleware to proxy (#84127)
Stacked to https://github.com/vercel/next.js/pull/84119

This PR adds a codemod for renaming `middleware` to `proxy`. Below are
the behaviors:

- Rename `middleware.*`, `src/middleware.*` to `proxy.*`, `src/proxy.*`
- Rename function/variable exports from `middleware` to `proxy`. Default
exports are skipped.
2025-10-09 02:03:52 +02:00
Jiwon Choi 643eb60de0 [Breaking] Remove AMP codemod (#84356) 2025-09-30 18:39:18 +02:00
Hendrik Liebau 4b66771895 Remove deprecated legacyBehavior and passHref prop from Link component (#83003)
The `legacyBehavior` prop of the `Link` component has been deprecated
since #77473. For Next.js 16, we're finally removing support for it.
Consequently, we're also removing support for the `passHref` prop, which
was only useful in conjunction with the `legacyBehavior` prop.

A [codemod is
available](https://nextjs.org/docs/app/guides/upgrading/codemods#new-link)
to help you automatically upgrade your codebase.

reverts #77473

---------

Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-08-26 14:04:27 +02:00
Ben Gubler c57fe2561c feat: add a codemod to migrate from the deprecated "next lint" command (#82685)
## Add codemod to migrate from `next lint` to ESLint CLI

This PR introduces a new codemod `next-lint-to-eslint-cli` that helps
users migrate away from the deprecated `next lint` command to using
ESLint directly, in preparation for Next.js 16 where `next lint` will be
removed.

### What it does

The codemod automates the migration process by:

1. **Updating package.json scripts** - Replaces all `next lint` commands
with `eslint` equivalents
- Maps Next.js-specific flags (`--strict` → `--max-warnings 0`,
`--dir`/`--file` → paths)
   - Preserves other ESLint-compatible flags
- Handles complex scripts with pipes, redirects, and multiple commands

2. **Managing ESLint configuration**
   - Creates a new flat config (`eslint.config.mjs`) if none exists
   - Updates existing flat configs to include Next.js rules
   - Provides guidance for legacy configs that need manual migration

3. **Installing dependencies automatically**
- Adds required packages: `eslint`, `eslint-config-next`,
`@eslint/eslintrc`
   - Detects and uses the project's package manager (npm/yarn/pnpm/bun)
   - Falls back to manual instructions if installation fails

### Usage

```bash
npx @next/codemod@latest next-lint-to-eslint-cli .
```

### Example transformations

```json
// Before
{
  "scripts": {
    "lint": "next lint",
    "lint:fix": "next lint --fix",
    "lint:strict": "next lint --strict --dir src"
  }
}

// After
{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint --fix .",
    "lint:strict": "eslint --max-warnings 0 src"
  }
}
```

### Why this change?

- `next lint` is being deprecated and will be removed in Next.js 16
- ESLint v9+ flat config is becoming the standard
- Direct ESLint usage provides more flexibility and better ecosystem
compatibility
- Reduces Next.js maintenance burden of wrapping ESLint functionality

The codemod ensures a smooth transition path for existing Next.js
projects while following ESLint best practices.
2025-08-19 13:27:17 -07:00
Will Binns-Smith be8275c86c @next/codemod: Add experimental.turbo to turbopack codemod for Next.js configs (#82134)
This adds a new transform to `@next/codemod` that updates
`next.config.{js,ts}` that updates the deprecated `experimental.turbo`
property to the new top-level `turbopack` property.

Details:
- Only operates on files called next.config.js or next.config.ts, in the
case the codemod tool is run on a large codebase.
- Updates _any_ object literal with a `experimental.turbo` property to
use `turbopack`. Since this transform is constrained to Next.js configs,
there shouldn’t be many false positives.
- Much of this change was written by Copilot. I simplified it, and
refactored it to make it more readable and safe.

Test Plan:
- `pnpm run build && pnpm test -- -t
next-experimental-turbo-to-turbopack` in the codemod directory
- Tested on several publicly available next configs that used the
deprecated property
2025-07-29 18:30:20 -07:00
Jiwon Choi 60b96e82be Revert "codemod: replace revalidate(Tag|Path) to expire(Tag|Path)" (#73269)
### Why?

Follow-up of https://github.com/vercel/next.js/pull/73193, as we
undeprecate revalidate APIs, the codemod should be reverted as well.
Fortunately, there were no docs change.

Reverts vercel/next.js#72826
2024-11-27 17:37:46 +00:00
Jiwon Choi 2d063a7971 codemod: replace revalidate(Tag|Path) to expire(Tag|Path) (#72826)
### Why?

We are renaming `revalidate(Tag|Path)` to `expire(Tag|Path)`.

Closes NDX-482

---------

Co-authored-by: Zack Tanner <zacktanner@gmail.com>
2024-11-15 23:38:25 +09:00
Hendrik Liebau 0354e5c193 Delete obsolete codemod next-dynamic-access-named-export (#72016) 2024-10-29 11:58:40 +00:00
Jiachi Liu b524c36235 codemod: make parser more comptible (#71122) 2024-10-11 15:05:52 +02:00
Jiachi Liu a7cd0c01e0 codemod: type cast async api calls in non entry file exports (#71040) 2024-10-09 21:59:56 +02:00
Jiwon Choi f9d4066078 feat(next-codemod): add app-dir-runtime-config-experimental-edge (#70968)
### Why?

We had breaking change in App Router at
https://github.com/vercel/next.js/pull/70480 where it strictly checks
`runtime` route segment config. If it is set to `experimental-edge`,
will throw. Therefore we support a codemod to replace it to `edge`.
2024-10-08 19:11:23 +00:00
Jiachi Liu 47030ae23d codemod: fix missing route transform (#70959) 2024-10-08 16:38:45 +02:00
Jiachi Liu f5d2f4cbce codemod: improve dynamic api codemod cases (#70593) 2024-10-01 21:36:55 +00:00
Jiachi Liu 952ecb2c10 Codemod for Async Request API (#69572) 2024-09-23 22:33:11 +02:00
Jiwon Choi 0090faa253 feat(next): codemod for removed geo and ip of NextRequest (#70064)
> [!NOTE]
> This codemod requires to install the `@vercel/functions` package.

### Why?

Codemod support for breaking change at
https://github.com/vercel/next.js/pull/68379. It removed the `ip`, and
`geo` properties from the `NextRequest` type. The `NextRequest` type was
mostly used in the `middleware` and `route`.



### How?

The codemod replaces the `ip`, and `geo` properties from the
`NextRequest` with corresponding `@vercel/functions` features.

#### Accessing NextRequest Value

When a file uses `NextRequest`, we look if there's an access to the type
with `geo` or `ip`. This targets destructuring and direct access.

```ts
export function GET (req: NextRequest) {
  const { geo, ip: ipAlias, pathname } = req // destructuring
  // direct access
  req.geo
  req.ip
}
```

Declares a variable based on the identifier within the object. If it was
aliased, we use the aliased name.

```ts
import { geolocation, ipAddress } from '@vercel/functions'

export function GET (req: NextRequest) {
  const { pathname } = req // destructuring
  const geo = geolocation(req)
  const ipAlias = ipAddress(req)
  // direct access
  geolocation(req)
  ipAddress(req)
}
```

#### Accessing NextRequest Types

When the file has accessed the `geo | ip` type from `NextRequest`, we
replace with the corresponding types.

```ts
import type { NextRequest } from 'next/server'

export function GET (req: NextRequest) {
  const ip = '...' as NextRequest['ip']
  const geo = { ... } as NextRequest['geo']
}
```

Since the type for `ip` is `string | undefined`, we explicitly replace
it. For `geo`, we replace with the `Geo` type.

```ts
import type { NextRequest } from 'next/server'
import type { Geo } from '@vercel/functions'

export function GET (req: NextRequest) {
  const ip = '...' as string | undefined
  const geo = { ... } as Geo
}
```

### Ref

Behavior FYI:
https://github.com/vercel/next.js/pull/70064#discussion_r1768718840,
https://github.com/vercel/next.js/pull/70064#discussion_r1768722282
Closes NDX-291

---------

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>
Co-authored-by: Donny/강동윤 <kdy1997.dev@gmail.com>
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
2024-09-24 01:42:16 +09:00
Sebastian "Sebbie" Silbermann c3475da068 Run @next/codemod tests in CI (#70248)
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
2024-09-19 13:28:38 +00:00
Jiachi Liu c8925c36db codemod: add next/dynamic imports codemod (#67126)
### What

Provide a codemod to transform the promise of the access to named export
properties in dynamic import `next/dynamic`, this codemod transform all
the `next/dynamic` imports to ensure returning an object value with
`default` property, aligning with what `React.lazy` is returning

### Why

Follow up for #66990 

It's not allowed to do dynamic import and access it's named export while
using `next/dynamic` in server component, and the dynamic import module
is from a client component. It's like accessing the nested client side
property of a module
2024-06-25 12:17:44 +00:00
Jiachi Liu 164e43912d codemods: migrate viewport related metadata export to viewport export (#57436)
This PR adds the codemods transforming certain fields from `metadata`
export to `viewport` export, will still preserve rest metadata export
properties. We don't cover `generateMetadata` to `generateViewport` as
there might be more complex logic inside the function which is hard to
apply the codemods rules.

TLDR: Codemods for #57302
2023-10-25 16:02:14 -07:00
Jiachi Liu 194e94ed6e codemod: migrate ImageResponse imports (#57074)
Adding codemod for #56662 for easier migration of `ImageResponse` from `"next/server"` to `"next/og"`
2023-10-19 20:02:25 +00:00
Steven d3e576dba3 fix: codemod should preserve type only import (#46512)
This PR is similar to PR #46460, but applies the patch to all our codemods.
2023-02-27 21:36:26 +00:00
John Daly 54266bb590 [next/codemod]: Preserve type-only imports when using next-image-to-legacy-image (#46460
<!--
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:
-->

Fix for https://github.com/vercel/next.js/issues/46459

In order to test this, I've updated the `next-image-to-legacy-image`
tests to use fixtures that are written in TypeScript. I've disabled
type-checking and linting on those test fixtures, because they are
pretty noisy.

## Bug

- [x] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-02-27 12:06:48 +01:00
Steven b954bbe676 fix: codemod next/image within monorepo (#46047)
Fix for running the `next/image` codemod within a monorepo

Related to https://twitter.com/codercatdev/status/1625972398448078848

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-02-17 18:35:41 -08:00
Steven 8163284e87 fix: next-image-experimental codemod (#45970)
This PR fixes `next/image` codemods and makes sure that the tests are properly testing the codemods using the `tsx` parser. This is accomplished by make sure each codemod declares the `tsx` parser instead of the CLI.

Related to: https://twitter.com/styfle/status/1625992439428263937
2023-02-17 01:36:09 +00:00
Hannes Bornö f1f0e78428 Add next/font imports codemod (#45740)
Add `built-in-next-font` codemod that transforms `@next/font` imports to
`next/font` and then uninstalls the `@next/font` package.

Tested locally with npm, yarn and pnpm.

Fixes NEXT-453

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-02-16 15:39:19 +01:00
Ishaq Ibrahim 29c5acd33b issue-41925 fix: skip duplicate props when transferring props from anchor to link (#42158)
Fixes issue #41925 by skipping duplicate props. I've tested the changes
locally - the duplicate prop is being skipped successfully. The
new-link.test.js suite is also passing.

<!--
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 that you're making:
-->

## Bug

- [x] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Co-authored-by: Ishaq Ibrahim <ishaq.ibrahim@convertdigital.com.au>
2022-10-30 13:09:14 -07:00
Steven 6fb9a192a7 Update next-image-experimental codemod to handle loaders (#41633)
As a follow up to #41585, this PR updates the `next-image-experimental`
codemod to change `loader` to `loaderFile`.
2022-10-21 15:26:42 -07:00
Steven c1de0c0ce6 Add codemods for next/image (#41004)
This adds two codemods for `next/image`.

The first codemod a safe solution to upgrade from 12 to 13 by swapping
to `next/legacy/image`.

The second codemod is an experimental solution that attempts to automate
the [migration
guide](https://nextjs.org/docs/api-reference/next/future/image#migration).
2022-10-11 13:44:36 -07:00
Tim Neutkens 20e5fed1cf Handle styled-jsx in newLinkBehavior codemod (#36628)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2022-05-02 19:07:14 +02:00
Tim Neutkens c232d3856a Add string children case for newNextLinkBehavior codemod (#36516) 2022-04-27 18:39:56 +02:00
Tim Neutkens 489e65ed98 Rework <Link> behavior (backwards compatible) (#36436)
Fixes https://github.com/vercel/next.js/discussions/32233

⚠️ If you're looking at this PR please read the complete description including the part about incremental adoption.

## TLDR:

Official support for `<Link href="/about">About</Link>` / `<Link href="/about"><CustomComponent /></Link>` / `<Link href="/about"><strong>About</strong></Link>` where `<Link>` always renders `<a>` without edge cases where it doesn’t render `<a>`. You'll no longer have to put an empty `<a>` in `<Link>` with this enabled.

## Full context

### Changes to `<Link>`

- Added an `legacyBehavior` prop that defaults to `true` to preserve the defaults we have today, this will allow to run a codemod on existing codebases to move them to the version where `legacyBehavior` becomes `false` by default
- When using the new behavior `<Link>` always renders an `<a>` instead of having `React.cloneElement` and passing props onto a child element
- When using the new behavior props that can be passed to `<a>` can be passed to `<Link>`. Previously you could do something like `<Link href="/somewhere"><a target="_blank">Download</a></Link>` but with `<Link>` rendering `<a>` it now allows these props to be set on link. E.g. `<Link href="/somewhere" target="_blank"></Link>` / `<Link href="/somewhere" className="link"></Link>`

### Incremental Adoption / Codemod

The main reason we haven't made these changes before is that it breaks pretty much all Next.js apps, which is why I've been hesitant to make this change in the past. I've spent a bunch of time figuring out what the right approach is to rolling this out and ended up with an approach that requires existing apps to run a codemod that automatically opts their `<Link>` usage into the old behavior in order to keep the app functioning.

This codemod will auto-fix the usage where possible. For example: 

- When you have `<Link href="/about"><a>About</a></Link>` it'll auto-fix to `<Link href="/about">About</Link>`
- When you have `<Link href="/about"><a onClick={() => console.log('clicked')}>About</a></Link>` it'll auto-fix to `<Link href="/about" onClick={() => console.log('clicked')}>About</Link>`
- For cases where auto-fixing can't be applied the `legacyBehavior` prop is added. When you have `<Link href="/about"><Component /></Link>` it'll transform to `<Link href="/about" legacyBehavior><Component /></Link>` so that your app keeps functioning using the old behavior for that particular link. It's then up to the dev to move that case out of the `legacyBehavior` prop.


**This default will be changed in Next.js 13, it does not affect existing apps in Next.js 12 unless opted in via `experimental.newLinkBehavior` and running the codemod.**

Some code samples of what changed:

```jsx
const CustomComponent = () => <strong>Hello</strong>

// Legacy behavior: `<a>` has to be nested otherwise it's excluded

// Renders: <a href="/about">About</a>. `<a>` has to be nested.
<Link href="/about">
  <a>About</a>  
</Link>

// Renders: <strong onClick={nextLinkClickHandler}>Hello</strong>. No `<a>` is included.
<Link href="/about">
  <strong>Hello</strong>
</Link>


// Renders: <strong onClick={nextLinkClickHandler}>Hello</strong>. No `<a>` is included.
<Link href="/about">
  <CustomComponent />
</Link>

// --------------------------------------------------
// New behavior: `<Link>` always renders `<a>`

// Renders: <a href="/about">About</a>. `<a>` no longer has to be nested.
<Link href="/about">
  About
</Link>

// Renders: <a href="/about"><strong>Hello</strong></a>. `<a>` is included.
<Link href="/about">
  <strong>Hello</strong>
</Link>

// Renders: <a href="/about"><strong>Hello</strong></a>. `<a>` is included.
<Link href="/about">
  <CustomComponent />
</Link>
```

---


## Feature

- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`


Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-04-25 22:01:30 +00:00
Tim Neutkens c5b5c43e3d Add codemod for files that do not support the new React JSX transform (#21281)
Previously our automatic React injection approach injected `import React from 'react'` automatically whenever JSX was detected. The new official JSX transform solves this by enforcing importing `React` when it is used.

This codemod automatically converted files that are using a "global React variable" to use `import React from 'react'`
2021-01-18 15:17:10 +00:00
Tim Neutkens 62031ff24f Move next-codemod to Next.js monorepo (#15536) 2020-08-10 11:14:53 +02:00