'<Link> does not work as expected in NextJS
I am working on creating a Next.js app and part of it requires me to create a dynamic route on click of a card component. However, after wrapping my Cards with the <Link>
from Next.js, I am unable to navigate to the page as nothing happens on click. I tried adding an <a>
tag under my Link
and it worked. I am coming from react-router, and felt that just adding the <Link>
should help navigate. Can someone explain the need for a <a>
tag inside the Link component?
Below is the code that I have:
import React from 'react';
import OptionsDropdown from './components/OptionsDropdown';
import Card from './components/card';
import Link from 'next/link';
const Browse = () => {
let filterByMenuEl = ['All items', 'Single items', 'Bundles'];
let sortByMenuEl = ['Price: Low to High', 'Price: High to Low', 'Most Favorited'];
let card1 = {
name: 'Collectible 1',
description: 'This is a description',
price: '0.11',
img: 'https://lh3.googleusercontent.com/Fviz0PWzUMQ98uvUZV8e_3y2R3D0nwk9q3jCQONoA2jh83vN2phkxEmLD3zpE1iiPOWNqh38rCqOC4agChgi704d0VGjgqwXrjiZ1Q=w600',
list_date: 'here'
}
let card2 = {
name: 'Collectible 2',
description: 'This is a description',
price: '0.12',
img: 'https://lh3.googleusercontent.com/8pQQRseehVjJ5PRZkXANawtaCooQfdTF9Ld3UvJVXxVaiixxM9x357NqLwFqindvDlKZ-XqbLytwzL-LxpiDPgJLIqOq5OHjhg5PAQ=w600',
list_date: 'here'
}
let card3 = {
name: 'Collectible 3',
description: 'This is a description',
price: '0.13',
img: 'https://lh3.googleusercontent.com/a2w4nmFDYU1Z5kimGQtymbw7E-Jj8zrZRGiKmkmv03e9z5VJAFFqSIsvq39EjtlETwluC9hDGx6EpS5YOCVN6X6pTlAiOpuD5tYW=w600',
list_date: 'here'
}
let card4 = {
name: 'Collectible 4',
description: 'This is a description',
price: '0.14',
img: 'https://lh3.googleusercontent.com/P0FjJQ-9_YlBUtl6-pg5tgz1KUOqxgGRnB0u4v3C6YnY14cMWealXb5u3O2OI_Zr-YxMYaRs_b4TVrBTZzXF18_zhZ1WWPsBYj6xyg=w600',
list_date: 'here'
}
let card5 = {
name: 'Collectible 5',
description: 'This is a description',
price: '0.15',
img: 'https://lh3.googleusercontent.com/alrw4OsjldeYC5WpJCfneeui2F4lNDU0xYLp80LA9horlf7wufhRG_2ln5u72PLaNh9tF_3WqSXZoCFTgIC9GatkKPobLQ5zYJgrug=w600',
list_date: 'here'
}
let card6 = {
name: 'Collectible 6',
description: 'This is a description',
price: '0.16',
img: 'https://lh3.googleusercontent.com/lGp0y5VfF0j0gpe9OcY34inan58xkJuH6i6vCtCempSbUBMsF0cXexO_rFJNixIQP3n27M0L1waBS8oUI_JayefpzmB9Lw3q5oq6=w600',
list_date: 'here'
}
let cards = [card1, card2, card3, card4, card5, card6];
return(
<div className='BrowsePage'>
<div className='browse-options'>
<div className='browse-results'>100,000 results</div>
{/* <div className='options-spacer' /> */}
<div className='browse-dropdowns'>
<OptionsDropdown title='Filter by' menuEl={filterByMenuEl} />
<OptionsDropdown title='Sort by' menuEl={sortByMenuEl} />
</div>
</div>
<div className='browse-main'>
{cards.map((e, index) => {
return (
<Link href={"/browse/" + e.name} key = {e.name} passHref={true}>
<Card
key={index}
name={e.name}
description={e.description}
price={e.price}
img={e.img}
/>
</Link>
)
})}
</div>
</div>
);
}
export default Browse;
Solution 1:[1]
Can someone explain the need for a tag inside the Link component?
You need <a>
tag inside the Next.js Link Component if the children is not a string. Otherwise you do not need <a>
tag. See: NextJS Link isn't rendering an anchor tag
From : https://github.com/vercel/next.js/blob/canary/packages/next/client/link.tsx
Some thoughts on the <a>
tag:
Content within each
<a>
should indicate the link's destination. If the href attribute is present, pressing the enter key while focused on the<a>
element will activate it. See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a<a>
is a tag that allows other elements within it to be right-clicked and has the options 'Open Link in New Tab', 'Copy Link Address', etc. (This is why I use this component.)
Solution 2:[2]
I think problem is in your slug routing. Please check out Next documentation where is described route with dynamic segments.
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${encodeURIComponent(post.slug)}`}>
<a>{post.title}</a>
</Link>
</li>
))}
</ul>
)
}
Solution 3:[3]
Not sure exactly what your issue is but here is how you can use dynamic next/link:
{myArray.map((item) => (
<NextLink href={`/something/${item.slug}`} passHref>
<a href={`/something/${item.slug}`}>
Dynamic link for {item.id}
</a>
</NextLink>
))}
Quick how to:
- Wrap NextLink around an
a
tag - Add
href
property on both - Add
passHref
property on NextLink to avoid 2 a tags rendering in html
Solution 4:[4]
Just add rel="noopener" as below , If it doesn't works then try adding rel="noopener noreferrer"
<NextLink href={`/something/${item.slug}`} passHref>
<a href={`/something/${item.slug}`} rel="noopener">
Dynamic link for {item.id}
</a>
</NextLink>
))}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | BloodOverdrive |
Solution 3 | Benjamin Carlson |
Solution 4 | Learn More |