typescriptbeginner

Active Navigation Link Component

Build a navigation component that highlights the active route using usePathname.

typescript
'use client';

import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { cn } from '@/lib/utils';

interface NavLink {
  href: string;
  label: string;
  icon?: React.ReactNode;
}

const navLinks: NavLink[] = [
  { href: '/', label: 'Home' },
  { href: '/dashboard', label: 'Dashboard' },
  { href: '/projects', label: 'Projects' },
  { href: '/settings', label: 'Settings' },
];

export function Navigation() {
  const pathname = usePathname();

  function isActive(href: string): boolean {
    if (href === '/') return pathname === '/';
    return pathname.startsWith(href);
  }

  return (
    <nav className="flex gap-1">
      {navLinks.map((link) => (
        <Link
          key={link.href}
          href={link.href}
          className={cn(
            'px-3 py-2 rounded-lg text-sm font-medium transition-colors',
            isActive(link.href)
              ? 'bg-blue-500/10 text-blue-500'
              : 'text-gray-400 hover:text-white hover:bg-white/5'
          )}
        >
          {link.label}
        </Link>
      ))}
    </nav>
  );
}

// Breadcrumb from pathname
export function Breadcrumb() {
  const pathname = usePathname();
  const segments = pathname.split('/').filter(Boolean);

  return (
    <nav className="flex items-center gap-2 text-sm text-gray-400">
      <Link href="/" className="hover:text-white">Home</Link>
      {segments.map((segment, i) => {
        const href = '/' + segments.slice(0, i + 1).join('/');
        const isLast = i === segments.length - 1;
        return (
          <span key={href} className="flex items-center gap-2">
            <span>/</span>
            {isLast ? (
              <span className="text-white capitalize">{segment}</span>
            ) : (
              <Link href={href} className="hover:text-white capitalize">{segment}</Link>
            )}
          </span>
        );
      })}
    </nav>
  );
}

Use Cases

  • navigation menus
  • sidebars
  • breadcrumbs

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.