Browse the docs
ComponentsNo. 35 of 109
Nav Link
A navigation link that marks the current page with aria-current and data-active. Supports asChild for router links.
Installation
pnpm dlx shadcn@latest add @corsair-ui/nav-linkNo setup needed: the CLI finds @corsair-ui in the shadcn registry directory. The files land in your project as source: edit them like your own code. More in Installation.
- Also adds
- utils
- npm
@radix-ui/react-slotclsxtailwind-merge
Examples
Current page
The active link gets aria-current="page". Use asChild with your router's link.
API
| Prop | Type | Default |
|---|---|---|
activeSets aria-current="page" and data-active. | boolean | false |
asChildRenders your router's link (next/link, react-router) instead of <a>. | boolean | false |
Accessibility
- The current page is announced through aria-current, not only by colour.
Compatibility
- Tailwind CSS
- 3.4 and 4, both checked in CI
- React
- 19
- Rendering
- Works in server components
Source
1 file, installed as source you own
nav-link.tsxView on GitHubimport { Slot } from "@radix-ui/react-slot";
import type { ComponentProps } from "react";
import { cn } from "@/registry/default/lib/utils";
interface NavLinkProps extends ComponentProps<"a"> {
/** Marks the link as the current page: sets `aria-current="page"` and `data-active`. */
active?: boolean;
/** Render the single child (next/link, a router Link, a plain `<a>`) with the link styles instead. */
asChild?: boolean;
}
/**
* A navigation link that knows whether it points at the current page. The
* active link gets `aria-current="page"`, which screen readers announce as
* "current page", and `data-active="true"` for styling. It stays a real link,
* so it is reached with Tab and followed with Enter, and shows a focus ring.
* Pass `asChild` to use your framework's link component.
*
* @example
* <NavLink asChild active={pathname === "/docs"}>
* <Link href="/docs">Docs</Link>
* </NavLink>
*/
function NavLink({ active = false, asChild = false, className, ...props }: NavLinkProps) {
const Comp = asChild ? Slot : "a";
return (
<Comp
data-slot="nav-link"
data-active={active}
aria-current={active ? "page" : undefined}
className={cn(
"text-muted-foreground hover:text-foreground data-[active=true]:text-foreground inline-flex items-center gap-1.5 rounded-md px-2 py-1.5 text-sm data-[active=true]:font-medium",
"transition-colors outline-none motion-reduce:transition-none",
"focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
/>
);
}
export { NavLink, type NavLinkProps };