I am trying to utilise NextJs's <Link />
tag to wrap a NextJs <Image />
in my application, to map over an array of data. If I place a <Link />
in a top level page ponent everything plays nicely and renders correctly. However if I try to abstract this out into a sub ponent and then embed the sub ponent in the page ponent I receive errors telling me Error: Multiple children were passed to <Link> with
hrefof
/test but only one child is supported
unless I remove all line breaks in the source code.
For example this works
// pages/index.js
import Link from 'next/link';
import Image from 'next/image';
export default function Home({links}) {
return (
<>
<div id="container">
<main>
{links.map(link => {
return <Link key={link.link} href={link.link}>
<a><Image src={link.imageUrl} width={400} height={400}/></a>
</Link>;
})
}
</main>
</div>
</>
);
}
export async function getStaticProps() {
const response = await fetch('http://localhost:3000/api/links');
const links = await response.json();
return {
props: {
links
},
}
}
This also works
// pages/index.js
import Links from '../ponents/Links';
export default function Home({links}) {
return (
<>
<div id="container">
<main>
<Links links={links}/>
</main>
</div>
</>
);
}
export async function getStaticProps() {
const response = await fetch('http://localhost:3000/api/links');
const links = await response.json();
return {
props: {
links
},
}
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';
export default function Links({links}) {
return links.map(link => {
return <Link key={link.link} href={link.link}><a><Image src={link.imageUrl} width={400} height={400}/></a></Link>;
},
);
}
However this fails
// pages/index.js
import Links from '../ponents/Links';
export default function Home({links}) {
return (
<>
<div id="container">
<main>
<Links links={links}/>
</main>
</div>
</>
);
}
export async function getStaticProps() {
const response = await fetch('http://localhost:3000/api/links');
const links = await response.json();
return {
props: {
links
},
}
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';
export default function Links({links}) {
return links.map(link => {
return <Link key={link.link} href={link.link}>
<a>
<Image src={link.imageUrl} width={400} height={400}/>
</a>
</Link>;
},
);
}
Any help appreciated!
I am trying to utilise NextJs's <Link />
tag to wrap a NextJs <Image />
in my application, to map over an array of data. If I place a <Link />
in a top level page ponent everything plays nicely and renders correctly. However if I try to abstract this out into a sub ponent and then embed the sub ponent in the page ponent I receive errors telling me Error: Multiple children were passed to <Link> with
hrefof
/test but only one child is supported https://nextjs/docs/messages/link-multiple-children
unless I remove all line breaks in the source code.
For example this works
// pages/index.js
import Link from 'next/link';
import Image from 'next/image';
export default function Home({links}) {
return (
<>
<div id="container">
<main>
{links.map(link => {
return <Link key={link.link} href={link.link}>
<a><Image src={link.imageUrl} width={400} height={400}/></a>
</Link>;
})
}
</main>
</div>
</>
);
}
export async function getStaticProps() {
const response = await fetch('http://localhost:3000/api/links');
const links = await response.json();
return {
props: {
links
},
}
}
This also works
// pages/index.js
import Links from '../ponents/Links';
export default function Home({links}) {
return (
<>
<div id="container">
<main>
<Links links={links}/>
</main>
</div>
</>
);
}
export async function getStaticProps() {
const response = await fetch('http://localhost:3000/api/links');
const links = await response.json();
return {
props: {
links
},
}
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';
export default function Links({links}) {
return links.map(link => {
return <Link key={link.link} href={link.link}><a><Image src={link.imageUrl} width={400} height={400}/></a></Link>;
},
);
}
However this fails
// pages/index.js
import Links from '../ponents/Links';
export default function Home({links}) {
return (
<>
<div id="container">
<main>
<Links links={links}/>
</main>
</div>
</>
);
}
export async function getStaticProps() {
const response = await fetch('http://localhost:3000/api/links');
const links = await response.json();
return {
props: {
links
},
}
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';
export default function Links({links}) {
return links.map(link => {
return <Link key={link.link} href={link.link}>
<a>
<Image src={link.imageUrl} width={400} height={400}/>
</a>
</Link>;
},
);
}
Any help appreciated!
Share Improve this question asked Feb 21, 2022 at 23:33 bryansmullenbryansmullen 651 gold badge2 silver badges5 bronze badges 1-
You can't have any extra spaces inside the
<Link>
tag. See Next.js: Error: React.Children.only expected to receive a single React element child. – juliomalves Commented Apr 27, 2022 at 22:24
2 Answers
Reset to default 3I'm using nextjs
with tailwindcss
.
When wrapping Image
with <></>
, my mouse didn't change to a little hand when hovering the element and clicking it does nothing.
And when wrapping with <a></a>
, the image doesn't line up with other elements even using flex justify-center items-center
on Link
(at least in my case).
So this is my solution:
const iconSize=20;
<Link href="/">
<div className="hover:cursor-pointer flex justify-center items-center">
<Image
src="/your_image.png"
alt="clickable image"
width={iconSize}
height={iconSize}
/>
</div>
</Link>
my nextjs version:
Next.js v12.2.3
try the code bellow
const CustomLink = React.forwardRef(({ href, children, ...rest }, ref) => (
<a href={href} ref={ref} {...rest}>
{children}
</a>
));
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';
export default function Links({links}) {
return links.map(link => {
return <Link key={link.link} passHref href={link.link}>
<Image src={link.imageUrl} width={400} height={400}/>
</Link>;
},
);
}