diff --git a/errors/invalid-new-link-with-extra-anchor.md b/errors/invalid-new-link-with-extra-anchor.md new file mode 100644 index 000000000000000..ffd4a7a9894eb9a --- /dev/null +++ b/errors/invalid-new-link-with-extra-anchor.md @@ -0,0 +1,21 @@ +# Invalid with child + +#### Why This Error Occurred + +Starting with Next.js 13, `` renders as ``, so attempting to use `` as a child is invalid. + +#### Possible Ways to Fix It + +Run the `new-link` codemod to automatically upgrade previous versions of Next.js to the new `` usage: + +```sh +npx @next/codemod new-link . +``` + +This will change `Home` to `Home`. + +Alternatively, you can add the `legacyBehavior` prop `Home`. + +### Useful Links + +- [next/link](https://nextjs.org/docs/api-reference/next/link) diff --git a/errors/manifest.json b/errors/manifest.json index 79a55d1d71831d0..3b8e2ba093e719e 100644 --- a/errors/manifest.json +++ b/errors/manifest.json @@ -694,6 +694,10 @@ "title": "nested-styled-jsx-tags", "path": "/errors/nested-styled-jsx-tags.md" }, + { + "title": "invalid-new-link-with-extra-anchor", + "path": "/errors/invalid-new-link-with-extra-anchor.md" + }, { "title": "returning-response-body-in-middleware", "path": "/errors/returning-response-body-in-middleware.md" diff --git a/packages/next/client/link.tsx b/packages/next/client/link.tsx index 5f89822900d42f5..3772932122e5dd4 100644 --- a/packages/next/client/link.tsx +++ b/packages/next/client/link.tsx @@ -408,6 +408,14 @@ const Link = React.forwardRef( } else { child = React.Children.only(children) } + } else { + if (process.env.NODE_ENV === 'development') { + if ((children as any)?.type === 'a') { + throw new Error( + 'Invalid with child. Please remove or use .\nLearn more: https://nextjs.org/docs/messages/invalid-new-link-with-extra-anchor' + ) + } + } } const childRef: any = legacyBehavior diff --git a/test/e2e/new-link-behavior/child-a-tag-error.test.ts b/test/e2e/new-link-behavior/child-a-tag-error.test.ts new file mode 100644 index 000000000000000..bce50f68b5055b7 --- /dev/null +++ b/test/e2e/new-link-behavior/child-a-tag-error.test.ts @@ -0,0 +1,42 @@ +import { createNext, FileRef } from 'e2e-utils' +import { getRedboxSource, hasRedbox } from 'next-test-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import webdriver from 'next-webdriver' +import path from 'path' + +const appDir = path.join(__dirname, 'child-a-tag-error') + +describe('New Link Behavior with child', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: { + pages: new FileRef(path.join(appDir, 'pages')), + 'next.config.js': new FileRef(path.join(appDir, 'next.config.js')), + }, + dependencies: { + next: 'latest', + react: 'latest', + 'react-dom': 'latest', + }, + }) + }) + afterAll(() => next.destroy()) + + it('should throw error with child', async () => { + const browser = await webdriver(next.url, `/`) + const link = await browser.elementsByCss('a[href="/about"]') + const msg = + 'Error: Invalid with child. Please remove or use ' + + if ((global as any).isDev) { + expect(next.cliOutput).toContain(msg) + expect(await hasRedbox(browser, true)).toBe(true) + expect(await getRedboxSource(browser)).toContain(msg) + expect(link).not.toBeDefined() + } else { + expect(link).toBeDefined() + } + }) +}) diff --git a/test/e2e/new-link-behavior/child-a-tag-error/next.config.js b/test/e2e/new-link-behavior/child-a-tag-error/next.config.js new file mode 100644 index 000000000000000..0d6071006ab351f --- /dev/null +++ b/test/e2e/new-link-behavior/child-a-tag-error/next.config.js @@ -0,0 +1,3 @@ +module.exports = { + reactStrictMode: true, +} diff --git a/test/e2e/new-link-behavior/child-a-tag-error/pages/about.js b/test/e2e/new-link-behavior/child-a-tag-error/pages/about.js new file mode 100644 index 000000000000000..e3c4a9ffa5c5abe --- /dev/null +++ b/test/e2e/new-link-behavior/child-a-tag-error/pages/about.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Page() { + return ( + <> +

About Page

+ +
Home + + + ) +} diff --git a/test/e2e/new-link-behavior/child-a-tag-error/pages/index.js b/test/e2e/new-link-behavior/child-a-tag-error/pages/index.js new file mode 100644 index 000000000000000..a12ba52a7b5eaed --- /dev/null +++ b/test/e2e/new-link-behavior/child-a-tag-error/pages/index.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Page() { + return ( + <> +

Home Page

+ + About + + + ) +}