# SkipLink

> Skip-to-main link shown on keyboard focus.

- Status: stable
- Group: navigation
- Page: https://www.digitaltableteur.com/design-system/components/skip-link
- Contract: https://www.digitaltableteur.com/contracts/v1/SkipLink.contract.json

## When to use

SkipLink lets keyboard and switch users bypass repeated chrome: visually hidden until focused, it surfaces as a high-contrast pill and jumps to the main content anchor (default `#main-content`). Render it as the first focusable element inside the layout so it is the very first Tab stop on every page, and keep the target id stable on the main wrapper. With no children the label is the translated "Skip to main content" (`skipToMainContent`); pass children only for a different target.

## When not to use

- Do not hide it with display:none or visibility:hidden; it must stay in the tab order; the component already handles visual hiding.
- Do not render it anywhere but first in the layout; it must be the first focusable element to be reachable.

## Look-alikes

The contract names no look-alike with a deciding condition.

## Props

| Prop | Type | Default | Description | Required |
| --- | --- | --- | --- | --- |
| `href` | `string` | `#main-content` | Target fragment for the main content region. Defaults to "#main-content". | No |
| `children` | `React.ReactNode` | none | Visible link text on focus. Defaults to the translated "Skip to main content" (`skipToMainContent`). | No |
| `className` | `string` | none | Optional utility classes on the link. | No |

## Variants

No variant dimensions and no props with a fixed set of values.

## Invalid combinations

The contract records no invalid combinations.

## Keyboard

| Key | Behaviour |
| --- | --- |
| Tab | First focusable element on the page; reveals the link. |
| Enter | Jumps focus to the main content target. |

## Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

| Level | Rule | How it is checked |
| --- | --- | --- |
| MUST | ARIA: Renders a real `<a href="#main-content">` so the browser moves focus to the target region natively; no ARIA needed. | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | ARIA: Visually hidden off-screen until focused, then revealed as a high-contrast pill; never `display:none` (which would drop it from the tab order). | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | Required stories produce no axe violations at the configured severity. | Automated by `npm run test:stories:matrix:ci`. WCAG 2.5.8. |
| MUST | The accessibility tree (role, name, state) matches the committed snapshot for every required story. | Automated by `npm run test:stories:matrix:ci`. WCAG 1.3.1, 4.1.2. |
| MUST | The component remains legible and operable under a real browser forced-colors: active pass. | Automated by `npm run test:stories:hc`. |
| MUST | Every documented keyboard interaction works as specified. | Not yet verified: no evidence record. WCAG 2.1.1, 2.1.2. |
| MUST | A human completed an end-to-end accessibility review of this component. | Manual review, last on 2026-11-04. |
| SHOULD | Render it first inside the layout/body so the first Tab press reveals it on every page. | Not stated in the contract. |
| SHOULD | Keep the target id stable on the main wrapper and matching href (default #main-content). | Not stated in the contract. |
| SHOULD | Keep the label an action phrase ("Skip to main content"); it is announced in isolation. | Not stated in the contract. |
| SHOULD | Re-test with Tab after layout changes; a skip link that never receives focus is dead code. | Not stated in the contract. |
| SHOULD NOT | Do not hide it with display:none or visibility:hidden overrides; it must remain focusable; the component already handles visual hiding. | Not stated in the contract. |
| SHOULD NOT | Do not add several skip links unless each targets a distinct landmark; one to main content is the baseline. | Not stated in the contract. |

## Install and import

- Install: `npm install @digitaltableteur/react` (version 0.9.1, restricted access on npm).
- Import: `import { SkipLink } from "@digitaltableteur/react";`
- Entry point: `@digitaltableteur/react/navigation` exports it too.
- Styles: import `@digitaltableteur/react/style.css` once at the app boundary.
- Also available as the custom element `<dt-skip-link>`; see the custom elements manifest.

## Links

- Machine-readable contract (Design System Contract 1.0): https://www.digitaltableteur.com/contracts/v1/SkipLink.contract.json
- Markdown version of this page: https://www.digitaltableteur.com/design-system/components/skip-link.md
- Component index as JSON: https://www.digitaltableteur.com/design-system/components.json
- All components: https://www.digitaltableteur.com/design-system/components
- Source: The implementation lives in a private repository. This page, its Markdown twin and the contract are generated from it at build time and are the public source of truth.
