Skip to content
Components

Link

An always-underlined navigation link with default or subtle emphasis. Render an anchor directly, or use asChild to style a router adapter while preserving its link behavior.

Preview

Props

  • variant
  • external
  • label
import { Link } from "@/components/ui/link"

<Link href="#guide">Read the guide</Link>

Usage

When to use

  • Navigate to a page, resource or section from text.
  • Place an underlined destination within a sentence.

When not to use

  • An action that changes the current page without navigating. Use Button.
  • A path through parent pages. Use Breadcrumb.

Variants

variant

default uses accent text; subtle uses secondary text.

import { Link } from "@/components/ui/link"

<Link href="#guide">Read the guide</Link>
<Link variant="subtle" href="#guide">Read the guide</Link>

Examples

Inline navigation

Read the installation guide before creating your first theme.

import { Link } from "@/components/ui/link"

<p className="text-sm text-text-primary">
  <span>Read the </span>
  <Link href="#installation">installation guide</Link>
  <span> before creating your first theme.</span>
</p>

External destination

import { Link } from "@/components/ui/link"

<Link external href="https://example.com/guide" target="_blank" rel="help">Open the guide</Link>

A single child provides the destination. Use the same composition with an application router adapter.

import { Link } from "@/components/ui/link"

<Link asChild variant="subtle">
  <a href="#project">View project</a>
</Link>

Do and don't

Do

  • Use meaningful destination text.
  • Use asChild for router adapters with their own destination props.
  • Make opening a new tab an explicit choice with target="_blank".

Don't

  • Do not use Link for actions that do not navigate; use Button.
  • Do not use external as a substitute for target.
  • Do not nest anchors.

Props

NameTypeValuesDefaultDescription
variantenumdefault | subtledefaultdefault uses accent text; subtle uses secondary text.
externalboolean-falseAdds a decorative external-link icon. Does not change the target.
asChildboolean-falseStyles a single child link or router adapter without a nested anchor.
hrefstring--Destination for the native anchor. A child router adapter may supply its own destination.
targetstring--Native navigation target. _blank merges noopener and noreferrer into rel.
relstring--Relationship values. Existing values are retained when safe values are added for _blank.

Slots

NameRequiredDescription
childrenyesVisible destination name, or the single child link when asChild is true.

Anatomy

PartDescription
rootAnchor or caller-supplied link with an underline and visible keyboard focus.
iconDecorative external-link icon, present only when external is true.

Accessibility

Role: link

KeysAction
TabFocus the link.
EnterFollow the focused link.
  • Both variants keep an underline so the link is distinguishable without color alone.
  • The external icon is decorative and does not change the accessible name.
  • external does not force a new tab. An explicit target="_blank" adds noopener noreferrer without dropping existing rel values.
  • asChild preserves the child destination, native attributes, event handlers and ref.

Install

npx shadcn add https://werewolf-ui.vercel.app/r/link.json

This also adds styles/werewolf.css, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after @import "tailwindcss", with a path relative to that CSS file (from app/globals.css it is @import "../styles/werewolf.css").