The best solution I'm familiar with is using the "Layout Segment" in Next.js.
It's important to note that it also works seamlessly with i18n routes – for example: /en/about/ and so on.
I highly recommend giving it a try:)
'use client'
import { items } from '@/utils/nav'
/* example
export const items = [
{
id: 1,
title: 'Home',
href: '/',
activeSegment: null,
},
{
id: 2,
title: 'About',
href: '/about',
activeSegment: 'about',
},
...
]
*/
import Link from 'next/link'
import { useSelectedLayoutSegment } from 'next/navigation'
...
// Inside you client component
const activeSegment = useSelectedLayoutSegment()
....
<nav>
{items.map((item) => (
<Link
key={item.id}
href={item.href}
className={activeSegment === item.activeSegment ? 'text-primary font-semibold' : 'text-muted-foreground'}
>
{item.title}
</Link>
))}
</nav>
...
For further details, see the official docs