---
title: Link
description: Styled anchor with external link support
visibility: guest
draft: false
---

# Link

A styled anchor element with variants, underline control, and external link support.

## Live Sandbox

This is a hydrated playground for the component. Toggle "Live preview" on the block below to swap the static HTML render for a real Livewire instance — every prop in the component's sandbox schema becomes an editable form field inside the iframe, so you can try different prop combinations live without writing any local code.

<!-- markdownlint-disable MD034 -->
:::preview{title="Sandbox" sandbox="link" props='{"href":"https://docs.wirekit.app","body":"Read the docs"}'}
<x-wirekit::link href="https://docs.wirekit.app">Read the docs</x-wirekit::link>
:::
<!-- markdownlint-enable MD034 -->

## Basic Usage

:::preview{title="Default link"}
<x-wirekit::link href="#">Documentation</x-wirekit::link>
:::

## Variants

:::preview{title="Link variants"}
<x-wirekit::row gap="lg">
    <x-wirekit::link href="#" variant="default">Default</x-wirekit::link>
    <x-wirekit::link href="#" variant="subtle">Subtle</x-wirekit::link>
    <x-wirekit::link href="#" variant="muted">Muted</x-wirekit::link>
</x-wirekit::row>
:::

## External Links

External links automatically get `target="_blank"`, `rel="noopener noreferrer"`, and a small arrow icon.

:::preview{title="External link"}
<x-wirekit::link href="#" :external="true">GitHub Repository</x-wirekit::link>
:::

## Underline Styles

:::preview{title="Underline options"}
<x-wirekit::row gap="lg">
    <x-wirekit::link href="#" underline="hover">Hover underline (default)</x-wirekit::link>
    <x-wirekit::link href="#" underline="always">Always underlined</x-wirekit::link>
    <x-wirekit::link href="#" underline="none">No underline</x-wirekit::link>
</x-wirekit::row>
:::

## In Context

:::preview{title="Link within text"}
<x-wirekit::text>
    Read the <x-wirekit::link href="#">getting started guide</x-wirekit::link> to learn how to install WireKit in your project.
</x-wirekit::text>
:::

## Link styled as a button

Use `as="button"` for an action that should look like a link but be a real `<button>` — accessible and keyboard-operable, without a fake `href="#"`.

:::preview{title="Link as a real button"}
<x-wirekit::row gap="sm">
    <x-wirekit::link href="/docs">A navigation link</x-wirekit::link>
    <x-wirekit::link as="button" type="button">A link-styled action</x-wirekit::link>
</x-wirekit::row>
:::

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `href` | string\|null | `null` | Link URL |
| `variant` | string | `'default'` | Color: `default`, `subtle`, `muted` |
| `external` | bool | `false` | Opens in new tab with rel="noopener noreferrer" and external icon |
| `underline` | string | `'always'` | Underline behavior: `always`, `hover`, `none` |
| `as` | string | `'a'` | HTML element to render |
| `scope` | string\|null | `null` | Scoped personalization name |

## Accessibility

External links include an inline SVG icon with `aria-hidden="true"` to indicate they open in a new window. The `rel="noopener noreferrer"` attribute prevents the opened page from accessing the original window.

## Keyboard Interaction

| Key | Action |
|-----|--------|
| `Tab` | Move focus to the link |
| `Enter` | Activate the link (follow the URL) |

## Pitfalls

- **Don't add `rel="noopener"` manually on `target="_blank"` links.** WireKit auto-injects `rel="noopener noreferrer"` for `_blank` (CVE-class tabnabbing fix). Manual `rel` values are merged correctly, but it's redundant.
- **Don't use `<x-wirekit::link>` for purely decorative anchors.** It carries focus styles + a screen-reader hint for `_blank` targets — overhead for invisible navigation. A plain `<a>` is fine for those.

## Design Tokens

| Token | Used for |
| --- | --- |
| `--font-wk-sans` | Link font family |
| `--color-wk-accent` | `default` variant link color |
| `--color-wk-text-subtle` | `subtle` variant link color |
| `--color-wk-text-muted` | `muted` variant link color |
| `--transition-wk-duration` / `--transition-wk-easing` | Hover transition |

## Usage & Conventions

> **Prop conventions** — this component uses one or more of the shared semantic prop names (`intent` / `variant` / `tone` / `surface`). See [Prop naming conventions](/extending/prop-naming-conventions) for the canonical vocabulary, alias matrix, and decision tree.
