Using NextJs Link component to wrap an Image element can lead to errors when iterating over an array, unless it is positioned within the

I am currently working on implementing NextJs's <Link /> tag to wrap a NextJs <Image /> within my application in order to iterate over an array of data. Everything functions as expected and renders correctly when I place the <Link /> in a top-level page component. However, when I attempt to abstract this into a sub-component and then include the sub-component in the page component, I encounter errors indicating that

Error: Multiple children were passed to <Link> with 
hrefof/test
, but only one child is supported https://nextjs.org/docs/messages/link-multiple-children
unless I remove all line breaks from the source code.

For instance, the following setup 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 proves to be effective:

// pages/index.js
import Links from '../components/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
        },
    }
}
// components/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, the following setup fails:

// pages/index.js
import Links from '../components/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
        },
    }
}
// components/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>;
        },
    );
}

All assistance is greatly appreciated!

Answer №1

In my current project, I'm utilizing nextjs along with tailwindcss.
I encountered an issue where the cursor did not switch to a hand symbol when hovering over the element and clicking it had no effect. Additionally, when using <></> to wrap the Image, it caused alignment problems with other elements even with flex justify-center items-center applied to the Link.

After some experimenting, I came up with the following 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>

The version of nextjs I am using is:

Next.js v12.2.3

Answer №2

Check out the following code snippet

const CustomLink = React.forwardRef(({ href, children, ...rest }, ref) => (
  <a href={href} ref={ref} {...rest}>
    {children}
  </a>
));
// components/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>;
       },
   );
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

ReactJS problem with dynamically adding input fields

By clicking on the +Add Content button, I am attempting to dynamically add one cascaded form field internally. Although the array for the field is updating, the view remains unchanged. Interestingly, when I try to add the external field by clicking on the ...

The bidirectional data binding in isolated scope is malfunctioning in AngularJS

I've just started learning angularjs and I'm working with isolated scope. I seem to be having issues with two-way binding using isolated scope. Can someone please review my code and help me debug this issue? When I remove age : '=' from ...

When trying to use the `map: texture` with a new `THREE.Texture(canvas)

i'm trying to apply the texture from new THREE.Texture(canvas) to the PointsMaterial, but it's not working as expected. The canvas appears on the top right corner, however, only white points are visible in the CubeGeometry. var texture = new ...

Experiment with showcasing information via Mobx fetched from an API

I am currently working on a React app that pulls data about coins from an API. I successfully implemented it using useEffect, but now I am attempting to achieve the same functionality with Mobx. My goal is to create a store file that fetches the data from ...

How to remove an image input type using jQuery

Can anyone provide insight into the issue with these scripts? I am attempting to remove an input when it is clicked. The input is of type image, so CSS cannot be used. I have tried using JavaScript but it doesn't seem to be working. HTML <!doctyp ...

Collaborating with multiple forms and files in PHP using jQuery and AJAX operations

Need help with the title for this question. There are two input fields and buttons in index.php <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="POST"> <input type="text" class="for ...

Exploring a previously created Vue mini project that is experiencing technical issues

Hello everyone! I am revisiting a project that I haven't worked on in a while. I tried using Vue.js for the first time to create an archery calculator for kinetic energy, velocity, and more. Instead of setting up a full Vue app, I simply used a CDN l ...

Using AngularJS controller to implement filtering functionality

I am a beginner at using Angular and have successfully implemented a filter to translate text for localization in my HTML view: <input type="button" class="btn btn-link" value="{{'weeklyOrdersPage.reposting' | translate}}" ng-click="sortBy(&a ...

What is the best way to enhance a tool-tip with images or legends?

Currently, I have implemented a tool-tip feature which works for a text box. However, the issue is that users are unaware of the presence of the tool-tip for the text box until they hover over it. My question is, how can I make it more obvious to users t ...

I need assistance in locating an error; the error message states that $ is not defined and an object is expected

Issue with $ not being defined, object expected.. I am trying to verify if all sets of radio buttons are checked when a button is clicked! Please help. <script type="text/javascript> $(document).on('click', 'form', function () { ...

Using a Jquery selector with either the ID Regex or a repetitive class

There is a collection of similar elements with matching IDs Below are two methods for selecting them using Jquery: Select by ID + Regex (For example, How can I select an element by ID with jQuery using regex?) Add a redundant class to all the elemen ...

Transitioning from JQuery to JavaScript with Carousel Bootstrap 5

I would like to implement a bootstrap 5 carousel that displays multiple items and slides one at a time. My goal is to convert the existing Jquery code into pure Javascript so that I can eliminate the dependency on Jquery. I came across this solution which ...

personalized options for initiating and concluding html audio component

I am currently facing an issue with my html audio element that plays a track. The setup is quite straightforward: <audio controls loop="loop"> <source type="audio/wav" src="song.wav"> </audio> However, I need to create custom start ...

How can I close the sidebar with a single tap anywhere outside of it?

Is there a way to hide the sidebar when clicking anywhere on the screen? Can I show text when hovering over an image instead of having it always visible? function openNav() { document.getElementById("mySidenav").style.width = "300px"; document.getE ...

How can I integrate the native calendar of an Android device in Phonegap?

What is the best way to add an event to an Android device's calendar using phonegap? I need to make sure it works on Android Version 2.3 and above. The available plugins are not functioning correctly, so I am looking for alternative solutions. ...

Establishing the Initial State of React Context with Data from Apollo Query

In my React.js project, specifically with Next.js, I have implemented a global React context for managing user data. Here is how the context is structured: const UserContext = createContext<{ user: User | undefined; setUser: (u: User | undefined) =& ...

Obtain the leaf nodes from a combination of arrays and objects using Lodash

Here is the code structure I want to share with you before explaining my requirements. It displays the input array layout along with the desired outcome: [ { link: "someurl", name: "Foo", subCats: [ { link: "anotherurl", ...

Mongoose in Nodejs does not support the use of Aggregate as a function

Seeking assistance to rectify this issue, here is my mongoose code snippet for aggregation: export class GetVehiclesbyKotaCommandHandler { constructor(namaKota) { return new Promise((resolve, reject) => { VehiclesDB.find().populate({ ...

Embed a photo into a pop-up window

Is there a way to dynamically insert an image into a Modal by utilizing the value of the variable data-image? This variable will change based on the selected image. <script type="text/javascript"> $('#myModal').on('show.bs.m ...

In production mode, the Angular/JS Express app is stuck in an endless routing loop, while it functions perfectly in development mode

My webapp is constructed using generator-angular-fullstack. While it functions properly in development mode (grunt serve), I encounter a problem with what appears to be an endless routing loop when switching to production mode (grunt serve:dist). The outp ...