Experience System
Components

Link

Text navigation with underline and typography variants; compose with router links via asChild.

Read the design system documentation to review component usage and accessibility guidance.

Link styles inline navigation: underline behavior, focus-visible ring, and typography variants. The default element is a native <a>; use asChild to merge styles onto a routing library component while keeping keyboard and assistive behavior on the child.

Installation

The component is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.

Composition

Use the following composition for a standalone anchor, or wrap a single child when composing with a router link:

Link (renders <a> by default)
└── (children) — anchor text or rich content

Link asChild
└── (single child element — e.g. router Link or <a>)

With asChild, Link delegates to Slot.Root so the child receives merged props and linkVariants classes. The child should ultimately render a focusable, keyboard-activatable navigation target. See Radix Slot.

Usage

import { Link } from '@by/experience-system';

Link is a client component ('use client'). Use it inside a Client Component or a dynamic import when using the Next.js App Router.

<p>
  Read the <Link href="/system/overview">experience system overview</Link> for setup guidance.
</p>

Examples

Underline

underline controls whether the decoration is always visible, shown on hover, or hidden.

Colors

Default styling uses neutral text. Apply token utility classes for accent, muted, success, or inherited color.

Typography

variant sets base, sm, or inherit sizing. Use className="text-inherit" with inherit when the link should match the parent’s text style.

Base link: Documentation

Inherited link: Release notes

Small link: API reference

Composition

Use asChild with a single child—such as a router stub or an existing <a>—to keep app routing while preserving Link styles.

API Reference

Link extends React’s ComponentProps<'a'> for the default <a> element and adds linkVariants from variants.ts. When asChild is true, props merge onto the child per Radix Slot.Root. For the full set of native anchor attributes (href, target, rel, download, ARIA, etc.), see MDN HTMLAnchorElement and The anchor element.

PropTypeDefault
asChildbooleanfalse
Design-system extensionTypeDefault
underlinealways | hover | nonealways
variantinherit | base | sminherit

All standard React.ComponentProps<'a'> props are forwarded (for example href, className, onClick, children) when asChild is false.

Data attributeValues
data-slotlink
data-underlinealways | hover | none
data-variantinherit | base | sm

Accessibility

  • Provide a meaningful href (or an equivalent navigation target on the asChild element) and link text that describes the destination out of context.
  • When opening a new tab or window, set target="_blank" with rel="noopener noreferrer" and indicate the behavior in visible text or an accessible name.
  • Focus styles use focus-visible:ring-* on Link; avoid removing focus outlines without a replacement that meets WCAG 2.1 focus-visible requirements.
  • Native link keyboard behavior applies: Enter activates the focused link. See MDN Keyboard support for links.

Keyboard interactions

KeyDescription
EnterActivates the link when it has keyboard focus.
SpaceNot used for activation on native links (unlike buttons).

Source in the repo: packages/experience-system/src/components/Link/Link.tsx and variants.ts. Agent-oriented contracts: packages/experience-system/src/components/Link/Link.instructions.md.