Skip to main content

Link

Typographic navigation element designed for inline navigation inside paragraphs, lists, and breadcrumbs. For action-oriented links that require button affordance (padding/background), use Button with asChild instead.


Usage

Basic usage

import { Link } from '@nofinite/nui';

<Link href="/docs">Documentation</Link>;

Variants

<Link variant="default">Default</Link>
<Link variant="primary">Primary</Link>
<Link variant="muted">Muted</Link>
<Link variant="danger">Danger</Link>

Underline control

<Link underline="hover">Hover underline</Link>
<Link underline="always">Always underline</Link>
<Link underline="none">No underline</Link>

Automatically applies secure routing attributes.

<Link href="https://example.com" isExternal>
External resource
</Link>

Framework routing (polymorphic)

'use client';
import NextLink from 'next/link';
import { Link } from '@nofinite/nui';

<Link asChild>
<NextLink href="/card">Go to card</NextLink>
</Link>;

'use client';
import NextLink from 'next/link';
import { Button } from '@nofinite/nui';

<Button asChild variant="primary">
<NextLink href="/dashboard">Go to Dashboard</NextLink>
</Button>;

Props

PropTypeDefaultDescription
variant"default" | "primary" | "muted" | "danger""default"Visual color style
underline"none" | "hover" | "always""hover"Underline behavior
isExternalbooleanfalseAdds target="_blank" and rel="noopener noreferrer"
asChildbooleanfalseEnables polymorphic rendering via Slot for router integration
classNamestringCustom styles
childrenReactNodeLink content
...propsAnchorHTMLAttributesNative anchor props

Variants

Color variants

  • default — neutral text color
  • primary — accent navigation link
  • muted — low emphasis navigation
  • danger — destructive navigation

Underline variants

  • none — removes underline
  • hover — underline appears on hover
  • always — persistent underline

Guidelines

  • Use primary for contextual navigation emphasis
  • Use muted for secondary inline links
  • Use danger only for destructive navigation contexts
  • Prefer hover underline for body text readability

States

  • Default
  • Hover
  • Focus visible
  • Active (browser native)
  • Disabled (via native anchor behavior)
  • External link state

Keyboard Interaction

KeyBehavior
TabMoves focus to link
EnterActivates navigation
Shift + TabMoves focus backward

Accessibility

  • Uses semantic <a> element by default
  • Preserves accessibility when asChild is used
  • focus-visible outline ensures keyboard focus visibility
  • External links include security attributes preventing tabnabbing
  • Underline ensures link affordance in text contexts
  • Compatible with screen readers via native anchor semantics

Design Tokens

TokenUsage
--nui-space-1Inline gap spacing
--nui-font-sansFont family
--nui-weight-mediumText weight
--nui-radius-smFocus radius
--nui-fg-defaultDefault text color
--nui-color-primaryPrimary link color
--nui-fg-subtleMuted color
--nui-color-dangerDanger color

Best Practices

Do

  • Use for inline navigation inside text
  • Use asChild for framework router integration
  • Use isExternal for outbound links
  • Maintain underline in long-form content

Don’t

  • Use for button-like CTAs with backgrounds
  • Remove underline in dense paragraph navigation without other affordance
  • Use danger variant for non-destructive navigation