---
title: Skip Link
description: Drop-in WCAG 2.4.1 (Bypass Blocks) skip-link helper
visibility: guest
draft: false
related:
  - /components/main
  - /components/visually-hidden
---

# Skip Link

A drop-in WCAG 2.4.1 (Bypass Blocks) component. Renders as a visually-hidden anchor at the very top of the page; when a keyboard user lands on it via `Tab`, the anchor pops out as a high-contrast accent pill in the top-left of the viewport. Activating it jumps focus into the main landmark, letting keyboard users bypass repeated navigation chrome.

## Try it — Tab to reveal

The preview below ships a real skip-link. On a real page you place it as the **first child of `<body>`**, so the very first `Tab` after the page loads reveals it as a high-contrast accent pill.

This demo is embedded inside the docs page, so it is **not** the page's first tab-stop — pressing `Tab` here walks the docs page's own navigation instead (that is why a nav link, not the skip-link, takes focus). To reveal the skip-link in place: **click the box below, then press `Shift`+`Tab`** — focus steps back onto the skip-link (the preview's first focusable element) and it pops out in the top-left.

:::preview{title="Skip-link — hidden until keyboard focus"}
<x-wirekit::skip-link target="skip-link-preview-target" />

<div id="skip-link-preview-target" tabindex="-1" style="padding: 1.5rem; border: 1px solid var(--color-wk-border); border-radius: var(--radius-wk-md);">
    Click here, then press <kbd>Shift</kbd>+<kbd>Tab</kbd> to reveal the skip-link in the top-left.
</div>
:::

## Basic Usage

```blade
{{-- # 1. Place as the FIRST child of <body> so it's the first tab-stop. --}}
<body>
    <x-wirekit::skip-link />

    {{-- # 2. App-shell chrome (header, nav, sidebar...) --}}
    <x-wirekit::header>...</x-wirekit::header>

    {{-- # 3. Mark the main landmark with id="main-content" — the skip-link's default target. --}}
    <x-wirekit::main id="main-content">
        {{ $slot }}
    </x-wirekit::main>
</body>
```

The skip-link is invisible until a keyboard user presses `Tab`. Mouse users never see it. Screen readers announce it as a standard link.

## Custom Target

When your main landmark uses a different id (for example, an article shell that doesn't use `<x-wirekit::main>`), point `target` at the landmark's id:

```blade
{{-- # 1. Custom target id on the landmark element. --}}
<x-wirekit::skip-link target="article-content" />

<article id="article-content" tabindex="-1">
    {{ $slot }}
</article>
```

## Custom Label

The default label is `Skip to main content`. Override via the `label` prop or by passing slot content:

```blade
{{-- Variant A — label prop. --}}
<x-wirekit::skip-link label="Skip to product details" target="product-info" />

{{-- Variant B — slot content (wins over the label prop when present). --}}
<x-wirekit::skip-link target="product-info">
    Skip to product details
</x-wirekit::skip-link>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `target` | string | `'main-content'` | id (without leading `#`) of the target landmark |
| `label` | string | `'Skip to main content'` | Anchor text rendered when focused |
| `scope` | string\|null | `null` | Scoped personalization name |

## Accessibility

The skip-link satisfies [WCAG 2.4.1 Bypass Blocks](https://www.w3.org/WAI/WCAG21/Understanding/bypass-blocks.html) (Level A). Without it, keyboard users have to tab through every nav link, every sidebar item, and every header utility on every single page load — exhausting on multi-page workflows.

The component:

- Renders `<a href="#{target}">` so browser fragment navigation works natively.
- Is visually hidden by default via `sr-only`; reveals on `:focus-visible` as a themed pill positioned absolutely in the top-left of the viewport.
- Pairs with `<x-wirekit::main id="main-content">` which receives `tabindex="-1"` automatically — so the fragment navigation actually MOVES KEYBOARD FOCUS into the landmark (not just the viewport scroll position).
- Uses the active theme's accent surface (`--color-wk-accent` background + `--color-wk-accent-fg` text + `--shadow-wk-lg` shadow + `--radius-wk-md` radius), so it visually belongs to whatever theme preset is active.
- Carries a high `z-index` so the surfaced pill sits above sticky headers, modals, and other overlay chrome.

## Keyboard Interaction

| Key | Action |
| --- | --- |
| `Tab` (first press on page load) | Surfaces the skip-link as a focused pill |
| `Enter` / `Space` (while focused) | Activates the link; focus moves into the target landmark |
| `Tab` (while focused) | Skips past the link, hiding it again |

## Usage & Conventions

::: tip
Pair `<x-wirekit::skip-link>` with `<x-wirekit::main id="main-content">` and you get a fully wired WCAG 2.4.1 baseline in two lines.
:::
