Skip to content

TextLink

A link set in text: inline, in the colour of links, underlined. Named TextLink so it never clashes with a router’s Link.

import { TextLink } from '@zitdevs/ui';
<p>
Read <TextLink label="how we scope a project" href="/process" /> before you write, or see the{' '}
<TextLink label="Stripe API reference" href="https://docs.stripe.com/api" external />.
</p>

primary and quiet on light fields; inverse on the inverse field. Underlined at rest by default; underline="hover" suits a link that stands alone, outside a paragraph.

asChild renders the link’s one child instead of its own <a>: the child brings the element and its routing props, the link its look, words and state. See Router links.

import Link from 'next/link';
<TextLink asChild label="Pricing" tone="quiet">
<Link href="/pricing" />
</TextLink>;
Prop Type Default Notes
label string required Visible text and accessible name.
href string required Unless asChild, where the child brings it.
external boolean false Opens a new tab, as target="_blank" does too: see Accessibility.
tone 'primary' | 'quiet' | 'inverse' 'primary' inverse on the inverse field.
underline 'always' | 'hover' 'always' hover only for a link that stands alone.
labels Partial<TextLinkLabels> English { opensInNewTab }. es.textLink from labels/es.
asChild boolean false Renders its one child (a router’s link) with the link’s classes and words.
children ReactElement — With asChild, the element to render as. Its own children are replaced by the label.
ref Ref<HTMLAnchorElement> — The <a>, or the child.
className string — Merged last.
anything else <a> attributes — hrefLang, download, aria-*, data-*, handlers.

Exported types: TextLinkProps, TextLinkTone, TextLinkUnderline, TextLinkLabels, and the label sets textLinkLabels.

  • Underlined at rest by default. Inside a paragraph a link’s colour alone is not enough to find it: link blue against body text is 2.4:1, under the 3:1 WCAG 1.4.1 asks.
  • A link that opens a new tab says so: the arrow for the eye, and “(opens in a new tab)” off screen for a screen reader, which ends its name. It gets rel="noopener noreferrer", so the new page has no handle on this one.
  • Every tone reaches 4.5:1 at rest and on hover on its fields. The link draws the kit’s focus ring itself.

It is a link. It holds no state and renders as a Server Component, through a router’s link too.

link and link-hover (primary), muted and ink (quiet), on-inverse-muted and on-inverse (inverse); the focus ring.

Use instead: a call to action → Button (its link variant for a bold standalone link).