Skip to content

Commit

Permalink
Add helpful error for link with multiple children (vercel#25657)
Browse files Browse the repository at this point in the history
Makes sure a helpful error is shown for `<Link>` with multiple children



## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added

## 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.

## Documentation / Examples

- [ ] Make sure the linting passes
  • Loading branch information
timneutkens authored May 31, 2021
1 parent f817e60 commit 9890565
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 1 deletion.
36 changes: 36 additions & 0 deletions errors/link-multiple-children.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Multiple children were passed to <Link>

#### Why This Error Occurred

In your application code multiple children were passed to `next/link` but only one child is supported:

For example:

```js
import Link from 'next/link'

export default function Home() {
return (
<Link href="/about">
<a>To About</a>
<a>Second To About</a>
</Link>
)
}
```

#### Possible Ways to Fix It

Make sure only one child is used when using `<Link>`:

```js
import Link from 'next/link'

export default function Home() {
return (
<Link href="/about">
<a>To About</a>
</Link>
)
}
```
16 changes: 15 additions & 1 deletion packages/next/client/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,21 @@ function Link(props: React.PropsWithChildren<LinkProps>) {
}

// This will return the first child, if multiple are provided it will throw an error
const child: any = Children.only(children)
let child: any
if (process.env.NODE_ENV === 'development') {
try {
child = Children.only(children)
} catch (err) {
throw new Error(
`Multiple children were passed to <Link> with \`href\` of \`${props.href}\` but only one child is supported https://nextjs.org/docs/messages/link-multiple-children` +
(typeof window !== 'undefined'
? "\nOpen your browser's console to view the Component stack trace."
: '')
)
}
} else {
child = Children.only(children)
}
const childRef: any = child && typeof child === 'object' && child.ref

const [setIntersectionRef, isVisible] = useIntersection({
Expand Down
28 changes: 28 additions & 0 deletions test/acceptance/ReactRefreshLogBox.dev.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,34 @@ test('logbox: anchors links in error messages', async () => {
await cleanup()
})

test('<Link> with multiple children', async () => {
const [session, cleanup] = await sandbox()

console.log({ SANDBOX: session.sandboxDirectory })
await session.patch(
'index.js',
`
import Link from 'next/link'
export default function Index() {
return (
<Link href="/">
<p>One</p>
<p>Two</p>
</Link>
)
}
`
)

expect(await session.hasRedbox(true)).toBe(true)
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: Multiple children were passed to <Link> with \`href\` of \`/\` but only one child is supported https://nextjs.org/docs/messages/link-multiple-children"`
)

await cleanup()
})

test('<Link> component props errors', async () => {
const [session, cleanup] = await sandbox()

Expand Down

0 comments on commit 9890565

Please sign in to comment.