Frontend - NextJS
How to Create a NavLink in Next.js 15 (App Router) with Tailwind
Learn how to build a reusable NavLink component in Next.js 15 (App Router) using Tailwind CSS. We'll use `next/link`, the `usePathname` hook to highlight active links, and the `cn` function

When building navigation in modern Next.js (15 with the App Router), it's often useful to have a reusable NavLink component. A NavLink not only renders links with Tailwind CSS but also highlights the active route based on the current URL.
Why NavLink?
By default, Next.js provides the `Link` component for navigation:
import Link from "next/link";
export default function Example() {
return <Link href="/about">About</Link>;
}
However, it doesn’t tell you if the link is currently active. That’s where NavLink comes in: it compares the current path (using the `usePathname` hook) with the link’s href and applies styling conditionally.
Key Ingredients
- `Link` from `next/link` for navigation
- `usePathname` from `next/navigation` to get the current path
- `cn` function (className utility) to conditionally merge Tailwind classes
- Tailwind CSS for styling
- TypeScript and TSX for type-safe components
How It Works
The NavLink component is a client component (using the `\"use client\"` directive).
"use client";
import Link, { LinkProps } from "next/link";
import { usePathname } from "next/navigation";
import { cn } from "@/lib/utils";
interface NavLinkProps extends LinkProps {
children: React.ReactNode;
className?: string;
}
export function NavLink({ href, children, className }: NavLinkProps) {
const pathname = usePathname();
const isActive = pathname === href;
return (
<Link
href={href}
className={cn(
"transition-colors hover:text-black",
isActive ? "text-blue-600 font-semibold" : "text-gray-500",
className
)}
>
{children}
</Link>
);
}
Inside it, `usePathname()` provides the current route. If that matches the link’s href, we apply an `active` style (like bold text, underline, or a different color). The `cn` function makes managing these conditional Tailwind classes clean and readable.
Styling with Tailwind
Tailwind makes it easy to toggle classes for active and inactive states. For example, you might use `text-gray-500 hover:text-black` for inactive links and `text-blue-600 font-semibold` for the active one.
// Active link
"text-blue-600 font-semibold"
// Inactive link
"text-gray-500 hover:text-black"
Using NavLink
Now, navigation becomes super simple:
import { NavLink } from "@/components/NavLink";
export default function Navbar() {
return (
<nav className="flex gap-4">
<NavLink href="/">Home</NavLink>
<NavLink href="/about">About</NavLink>
<NavLink href="/contact">Contact</NavLink>
</nav>
);
}
Final Thoughts
With a simple NavLink
component:
- Your navigation is reusable
- It’s type-safe with TSX
- Styled cleanly with Tailwind
- Fully compatible with the Next.js App Router
A small detail like highlighting the current page dramatically improves the user experience.