When working with links in Next.js, it’s important to determine the current URL and assign a class to the active link so that it can be styled differently. This is particularly useful in the site header. Unfortunately, the default Link
component provided by next/link
doesn’t handle this automatically. However, there are two techniques that we can use to achieve this behavior.
The first technique is to add the logic to the children of the Link
component. Here’s a simple example:
import React from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
const menu = [
{ title: 'Home', path: '/home' },
{ title: 'Explore', path: '/explore' },
{ title: 'Notifications', path: '/notifications' },
]
const Sidebar = () => {
const router = useRouter()
return (
<div>
{menu.map((item, index) => (
<Link key={index} href={item.path}>
<a
className={`cursor-pointer ${
router.pathname === item.path
? 'text-blue-500'
: 'hover:bg-gray-900 hover:text-blue-500'
}`}
>
{item.title}
</a>
</Link>
))}
</div>
)
}
export default Sidebar
This technique is recommended as it is the simplest approach.
The second technique involves creating our own Link
component. We can store it in a file called MyLink.js
inside the /components
folder and import it instead of the default next/link
. Inside the component, we compare the current pathname with the href
prop of the component. If they match, we append the text-blue-500
class to the children. You can use your own classes, but in this example, we use a Tailwind class to make the text blue. Finally, we return the children with the updated class using React.cloneElement()
.
import React from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
const MyLink = ({ href, children }) => {
const router = useRouter()
let className = children.props.className || ''
if (router.pathname === href) {
className = `${className} text-blue-500`
}
return <Link href={href}>{React.cloneElement(children, { className })}</Link>
}
export default MyLink
Now, we can use this MyLink
component in other components:
import MyLink from 'components/MyLink'
// ...
<MyLink href="blog">
<a>Blog</a>
</MyLink>
<MyLink href="about">
<a>About</a>
</MyLink>
Using this technique, the code in your other components becomes simpler compared to the first technique, as the logic is now contained within the MyLink
component.