import Link from 'next/link'; import { usePathname } from 'next/navigation'; export default function NavLink({ href, children }) { const pathname = usePathname(); const isActive = pathname === href; return ( <Link href={href} className={isActive ? 'active' : 'inactive'} aria-current={isActive ? 'page' : undefined}> {children} </Link> ); } // Assume current pathname is '/about'
The component uses usePathname() to get the current path. It compares it to the href prop. If they match, isActive is true, so the a tag gets className 'active' and aria-current='page' for accessibility.
Next.js 14 app router provides usePathname from 'next/navigation' to get the current path. The other hooks are either from older versions or incorrect names.
import Link from 'next/link'; import { usePathname } from 'next/navigation'; export default function NavLink({ href, children }) { const pathname = usePathname(); const isActive = pathname === href; return ( <Link href={href} aria-current={isActive ? 'page' : undefined} className={isActive ? 'active' : 'inactive'}> {children} </Link> ); }
The code assigns const pathname = usePathname; without parentheses, so pathname is the function itself, not the current path string. The comparison pathname === href always fails.
const pathname = '/blog/post'; const href = '/blog'; const isActive = pathname === href;
The strict equality operator === checks for exact match. '/blog/post' is not equal to '/blog', so isActive is false.
Using pathname.startsWith(href) returns true if the current path begins with the parent link path, correctly highlighting parent links for nested routes.
Other options either check exact equality or wrong substring relations.