Link
A styled anchor component for navigation with built-in icon support
Import
import { Link } from '@heroui/react';Usage
import {Link} from "@heroui/react";
export function LinkBasic() {
  return (
    <Link href="#">
      Call to action
      <Link.Icon />
    </Link>
  );
}Anatomy
Import the Link component and access all parts using dot notation.
import { Link } from '@heroui/react';
export default () => (
  <Link href="#">
    Call to action
    <Link.Icon />
  </Link>
);Custom Icon
import {Link} from "@heroui/react";
import {Icon} from "@iconify/react";
export function LinkCustomIcon() {
  return (
    <div className="flex flex-col gap-3">
      <Link href="#">
        External link
        <Link.Icon className="ml-1.5 size-3">
          <Icon icon="gravity-ui:arrow-up-right-from-square" />
        </Link.Icon>
      </Link>
      <Link className="gap-1" href="#">
        Go to page
        <Link.Icon className="size-3">
          <Icon icon="gravity-ui:link" />
        </Link.Icon>
      </Link>
    </div>
  );
}Icon Placement
import {Link} from "@heroui/react";
export function LinkIconPlacement() {
  return (
    <div className="flex flex-col gap-3">
      <Link href="#">
        Icon at end (default)
        <Link.Icon />
      </Link>
      <Link className="gap-1" href="#">
        <Link.Icon />
        Icon at start
      </Link>
    </div>
  );
}Underline Variants
Control the underline behavior with the underline prop:
Underline on hover (default)
Hover to see underline animationAlways visible underline
Underline always visibleNo underline
Link without any underlineimport {Link} from "@heroui/react";
export function LinkUnderlineVariants() {
  return (
    <div className="flex flex-col gap-6">
      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">Underline on hover (default)</p>
        <Link href="#" underline="hover">
          Hover to see underline animation
          <Link.Icon />
        </Link>
      </div>
      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">Always visible underline</p>
        <Link href="#" underline="always">
          Underline always visible
          <Link.Icon />
        </Link>
      </div>
      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">No underline</p>
        <Link href="#" underline="none">
          Link without any underline
          <Link.Icon />
        </Link>
      </div>
    </div>
  );
}underline="hover"(default) - Animated underline appears on hoverunderline="always"- Underline always visible (50% opacity, 100% on hover)underline="none"- No underline
Underline Offset
Adjust the spacing between text and underline with the underlineOffset prop:
import {Link} from "@heroui/react";
export function LinkUnderlineOffset() {
  return (
    <div className="flex flex-col gap-4">
      <Link href="#" underline="hover" underlineOffset={1}>
        Offset 1 (default)
        <Link.Icon />
      </Link>
      <Link href="#" underline="hover" underlineOffset={2}>
        Offset 2
        <Link.Icon />
      </Link>
      <Link href="#" underline="hover" underlineOffset={3}>
        Offset 3
        <Link.Icon />
      </Link>
    </div>
  );
}underlineOffset={1}(default) - No spaceunderlineOffset={2}- 2px spacingunderlineOffset={3}- 4px spacing
Using with Routing Libraries
Use the asChild prop to compose Link with framework-specific links like Next.js:
import { Link } from '@heroui/react';
import NextLink from 'next/link';
export default function Demo() {
  return (
    <Link asChild underline="hover">
      <NextLink href="/about">
        About Page
        <Link.Icon />
      </NextLink>
    </Link>
  );
}Direct Class Application
Since HeroUI uses BEM classes, you can apply Link styles directly to any link element without using asChild:
import NextLink from 'next/link';
// Apply classes directly
export default function Demo() {
  return (
    <NextLink href="/about" className="link link--underline-hover link--offset-1">
      About Page
    </NextLink>
  );
}
// Or with a native anchor
export default function NativeLink() {
  return (
    <a href="/about" className="link link--underline-always link--offset-2">
      About Page
    </a>
  );
}Available BEM classes:
- Base: 
link - Underline: 
link--underline-none,link--underline-hover,link--underline-always - Offset: 
link--offset-1,link--offset-2,link--offset-3 
Styling
Passing Tailwind CSS classes
import { Link } from '@heroui/react';
function CustomLink() {
  return (
    <Link
      href="#"
      className="text-lg font-bold text-accent hover:text-accent/80"
    >
      Custom styled link
    </Link>
  );
}Customizing the component classes
To customize the Link component classes, you can use the @layer components directive.
Learn more.
@layer components {
  .link {
    @apply font-semibold no-underline hover:underline;
  }
}HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.
CSS Classes
The Link component uses these CSS classes (View source styles):
Base Classes
.link- Base link styles
Underline Variants
.link--underline-none- No underline.link--underline-hover- Animated underline on hover (default).link--underline-always- Always visible underline
Underline Offset
.link--offset-1- No spacing (default).link--offset-2- 2px spacing.link--offset-3- 4px spacing
Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
- Focus: 
:focus-visibleor[data-focus-visible="true"] - Disabled: 
:disabledor[aria-disabled="true"] 
API Reference
Link Props
| Prop | Type | Default | Description | 
|---|---|---|---|
href | string | - | Destination URL for the anchor | 
target | string | "_self" | Controls where to open the linked document | 
rel | string | - | Relationship between the current and linked documents | 
download | boolean | string | - | Prompts file download instead of navigation | 
underline | "none" | "hover" | "always" | "hover" | Controls underline visibility and behavior | 
underlineOffset | 1 | 2 | 3 | 1 | Spacing between text and underline | 
asChild | boolean | false | Merge props with child element (useful for routing libraries) | 
isDisabled | boolean | false | Disables pointer and keyboard interaction | 
className | string | - | Custom classes merged with the default styles | 
children | React.ReactNode | - | Content rendered inside the link | 
onPress | (e: PressEvent) => void | - | Fired when the link is activated | 
autoFocus | boolean | - | Whether the element should receive focus on render | 
Link.Icon Props
| Prop | Type | Default | Description | 
|---|---|---|---|
asChild | boolean | false | Merge props with child element | 
children | React.ReactNode | - | Custom icon element; defaults to the built-in arrow icon when omitted | 
className | string | - | Additional CSS classes |