Skip to contentAsheeUIAsheeUI

Link

A destination stated as text, the anchor every navigation component in the framework renders.

A link is a destination a reader can enter, and the framework's navigation components render every one of their destinations through this component: a navbar's links, a footer's columns and a breadcrumb's steps are all Links. That is why it is worth understanding on its own, the emphasis axes, the external handling and the substitution are stated once, here, and inherited everywhere.

It renders a real anchor with a real destination. What it adds is a vocabulary for how loudly the link speaks, and an explicit statement of whether it leaves the site.

Usage

import { Link } from "@asheeui/web";

<Link href="/invoices">All invoices</Link>;

isExternal is the one prop that changes behaviour rather than appearance: it sets the target and relationship attributes an off-site destination needs and shows the affordance that says so.

Emphasis

Three axes, each with a default. variant says how much the link asks for, default, muted for navigation beside content, or subtle for a link inside a sentence that is already quiet. color is a role rather than a hex value. underline decides when the line appears: always for a link inside a run of text, hover for a link that is already recognisable, and never for one whose surroundings carry the meaning. size is the fourth: it scales the text and the icons beside it, so a link in a caption does not keep the size of a heading.

<Link href="/invoices" variant="muted" underline="always">
  March invoices
</Link>

The anchor it renders

Some props belong to the anchor rather than to the text. isExternal gives it the target and the relationship, and draws the external mark after the label; endIcon replaces that mark with content of your own. disabled refuses the press, states the condition with aria-disabled and drops the destination, so a link that is temporarily unreachable cannot be followed by accident.

Framework routers

TanStack Router and React Router name a destination to, not href. Both spellings are accepted:

// A plain anchor, no router involved.
<Link to="/components">Components</Link>

// The same call site, routed by TanStack.
<Link to="/components" component={RouterLink}>Components</Link>

With component set, to is forwarded to it, so the router handles the navigation as it would for any of its own links, and href is not passed, because a router link that receives both has two destinations. Without component, to becomes the anchor's href, which means a page can be written before the router exists and keep working after it is introduced. When both props are given, to wins.

Then there is component, which replaces the element: pass a framework's router link and its props and the link renders that instead, receiving the destination, the classes, the state and the press handler an anchor would have received. componentProps is merged last, so it takes precedence over the props the framework passes itself.

The substitution is the framework's shared seam rather than a Link feature: it is the same contract Image and Form use, and it is described in links and substitution.

Props

size, underline and isExternal are registered by the component as md, hover and false, so each resolves from the instance, then components.link, then that value. variant is not registered and falls back to default: the application's defaultVariant describes a control's surface, and a link has no surface. color is not registered either, it resolves from the application's defaultColor and then primary, which is what keeps a link the same accent as the button beside it.

Accessibility

  • The element is a real <a href>, so it is in the tab order and in the reading order without a tabindex, it is announced as a link, and it can be opened in a new tab or copied as a URL. The focus ring is drawn with focus-visible, so it appears for a keyboard and not for a mouse.
  • isExternal sets target="_blank" with rel="noopener noreferrer", so an off-site destination neither takes the page's context away silently nor keeps a handle on it.
  • Icon slots are presentational wrappers around the content you pass: the link's accessible name is its text, so a link whose only content is an icon needs its own aria-label.
  • disabled states the condition with aria-disabled and dims the text rather than hiding it. The href is kept, so the element is still announced as a link and still reachable by keyboard, the press is what is refused, not the existence of the destination. A control that vanishes from the tab order is one a reader cannot be told about.

A substituted component receives aria-current and aria-disabled the same way an anchor does, which is what lets the navigation components mark the current page through it: see links and substitution.