Ashan Priyadarshana
Ashan Priyadarshana

Reputation: 3619

Next.js: Error: React.Children.only expected to receive a single React element child

I'm having a component called Nav inside components directory and it's code is some thing like below:

import Link from 'next/link';

const Nav = () => {
    return(
        <div>
            <Link href="/">  <a> Home </a> </Link>
            <Link href="/about"> <a> About </a>  </Link>
        </div>
    )
}

export default Nav;

This gives me the error:

Error: React.Children.only expected to receive a single React element child.

But if I remove the <a> tags within <Link> components, I can view the pages, but then in the console I'm getting a warning of:

Warning: You're using a string directly inside <Link>. This usage has been deprecated. Please add an <a> tag as child of <Link>

So what am I doing wrong here?

Upvotes: 43

Views: 52318

Answers (9)

CopyLeft
CopyLeft

Reputation: 329

I landed here because I was having a similar issue in my Next.js app, but I would get a 500 error in browser console and the React.Children.only error in my terminal whenever I refreshed manually refreshed my app on any page.

The terminal output would provide a huge stack trace that pointed to next-server in my node_modules (node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js).

As it turns out, I was using styled-components with a boilerplate Next.js app setup by NX, and in my global app layout (src/app/layout.tsx), I had the StyledComponentsRegistry component as a parent of my main application, like so:

const RootLayout = ({ children }) => (
  <html lang="en">
    <body>
      <StyledComponentsRegistry>
        <>
          <div>header</div>
          <div>main content</div>
          <div>footer</div>
        </>
      </StyledComponentsRegistry>
    </body>
  </html>
);

It turns out that React.Children.only, and by extension StyledComponentsRegistry, did not consider the Fragment (<>) the child component since it's not rendered in the DOM when the page is built.

So instead, I replaced the wrapping Fragment (<>) with a div (<div>) and the error went away!

In other words, it looked like:

const RootLayout = ({ children }) => (
  <html lang="en">
    <body>
      <StyledComponentsRegistry>
        <div> {/* changed this <> to a <div> */}
          <div>header</div>
          <div>main content</div>
          <div>footer</div>
        </div> {/* changed this </> to a </div> */}
      </StyledComponentsRegistry>
    </body>
  </html>
);

(Hope this helps someone, and sorry to piggyback off an only somewhat related issue! There were no other questions addressing mine out there.)

Upvotes: 0

Siddhartha Mukherjee
Siddhartha Mukherjee

Reputation: 2943

If the child is <a> tag then add legacyBehavior. it will work

import Link from 'next/link'

function Legacy() {
  return (
    <Link href="/about" legacyBehavior>
      <a>About Us</a>
    </Link>
  )
}

export default Legacy

Upvotes: 2

Chris Perry
Chris Perry

Reputation: 7886

Check if inner content is empty

In addition to the scenarios covered by other answers, this error also gets fired when there's no content in between <Link> opening and closing tags.

For example:

<Link href='/'></Link>  // i am an error

Upvotes: 1

Zowy
Zowy

Reputation: 64

Im following the NextJs tutorial and space is not only the culprit. Semi colon also.

// without space, this will also not work because of the semi-colon
    function FirstPost() {
      return (
        <>
          <h1> First Post </h1>
          <h2>
            <Link href="/">
              <a>Back to Home</a>;
            </Link>
          </h2>
        </>
      );

// with space but without semi-colon will not also work
function FirstPost() {
  return (
    <>
      <h1> First Post </h1>
      <h2>
        <Link href="/">
          <a> Back to Home </a>
        </Link>
      </h2>
    </>
  );
}

Upvotes: 0

Abdullah Ansari
Abdullah Ansari

Reputation: 710

I was having the same issue there were no problems with spaces rather I was passing an integer inside Link

    <Link href={{
           pathname: `/dashboard/people`,
          query: { idPerson: 123 }}}>
       {123}
   </Link>

I resolved this error by parsing the integer using toString() method

    <Link href={{
         pathname: `/dashboard/people`,
         query: { idPerson: 123 }}}>
      {(123).toString()}
   </Link>

Upvotes: 1

Ani David
Ani David

Reputation: 141

Space between < Link > and < a > makes you error "Unhandled Runtime Error Error: Multiple children were passed to with href of / but only one child is supported https://nextjs.org/docs/messages/link-multiple-children Open your browser's console to view the Component stack trace."

Remove the space and it work fine.

import Link from "next/link";

const NavBar = () => {
    return (
        <nav>
            
           <Link href="/"><a>Home </a></Link>
           <Link href="/About"><a>About </a></Link>
            <Link href="/Contact"><a>Contact </a></Link>
        </nav>
    )
}

export default NavBar

Upvotes: 7

Nicolas Zozol
Nicolas Zozol

Reputation: 7038

I had a space that was considered as an undefined component

<Link href={to}><a className={'abc'}>{children}</a> </Link>

Removing the space, it was ok. 30 minutes lost only, thanks to experience and internet help.

Upvotes: 1

deadcoder0904
deadcoder0904

Reputation: 8683

I had the same issue as I was doing:

<Link href={`/tutorial/${tutorial.slug}`}>{tutorial.title}</Link>

The fix was to wrap it in an a tag:

<Link href={`/tutorial/${tutorial.slug}`}><a>{tutorial.title}</a></Link>

Upvotes: 5

Maniraj Murugan
Maniraj Murugan

Reputation: 9084

This issue is due to the space between <Link> tag and <a> tag.

So change your code like,

        <div>
            <Link href="/"><a> Home </a></Link>
            <Link href="/about"><a> About </a></Link>
        </div>

Reason for the change:

-> The <Link> can have only one child node and here the space between the link and a tag are considered as a child nodes.

-> So there are two child nodes (One is space and another is <a> tag) which is invalid and hence such error occurs.

Upvotes: 84

Related Questions