Components
Link
BetaStyled anchor component for inline body copy, standalone navigation items, and external references. Three variants cover the full range of link contexts on a travel site.
For the ultimate beach escape, consider the Maldives or the Seychelles . Both offer overwater villas and exceptional diving.
Purpose
The Link component styles anchor elements consistently across all contexts. It handles three distinct use cases:
- Inline — embedded within body copy. Always underlined to signal clickability without colour alone (WCAG 1.4.1).
- Standalone — a navigation link outside of paragraph text. No underline until hover; often appears in sidebars, footers, and breadcrumbs.
- External — links leaving the kuoni.co.uk domain. Shows a trailing arrow icon and opens in a new tab.
Usage
Reach for Link whenever the interaction is navigation — moving the user to a different URL — rather than an action that changes state or data. When the goal is an action (form submit, booking step, cancellation) rather than navigation, use a Button instead, even if it needs to look like a link inline.
Links appear everywhere navigation happens: inline within body copy and editorial content, as standalone items in sidebars, footers, and breadcrumbs, and as external references to third-party sites like ABTA or the CAA. Choose the variant that matches the context — see Variants below.
Anatomy
Book a safari holiday or browse our destination guides.
View all holiday types →- 1Anchor element — Native <a> with href, target, and rel. The component never strips these attributes.
- 2Text content — The visible link label. Sentence-case, specific enough to make sense out of context.
- 3External icon — ExternalLink icon (14 px) from lucide-react. Only shown for the external variant. Labelled "(opens in new tab)" for screen readers.
- 4Focus ring — 2 px teal ring with 2 px offset, visible only on keyboard focus (focus-visible).
Variants
Inline
Underlined by default. Use for links within sentences and paragraphs.
Explore the African savanna or discover remote Indian Ocean atolls.
Standalone
No underline at rest; underlines on hover. Use for navigation links that live outside body copy — footer columns, breadcrumb items, sidebar lists.
External
Shows a trailing icon, opens in a new tab, and adds rel="noreferrer noopener" automatically.
Dark colour (navigation)
Use color="dark" for links that appear in nav bars, sidebars, and other contexts where teal is too prominent.
Disabled
States
| State | Appearance |
|---|---|
| Default | Teal (#005B55), underlined (inline) or plain (standalone) |
| Hover | Teal-700 (#003D39), underlined (all variants) |
| Visited | Teal-700 (#003D39) — signals previously viewed destinations |
| Focus | 2 px teal ring, 2 px offset |
| Disabled | 40% opacity, pointer-events removed, tabIndex=-1 |
Best practices
Write link labels that describe the destination or action, not the mechanism.
'Read our Kenya safari guide' gives screen reader users the destination of the link without surrounding context.
Use generic labels like 'click here', 'read more', or 'learn more' without surrounding context.
'Click here' or 'Read more' alone is meaningless when read by a screen reader out of context.
Use the inline variant for any link embedded within a paragraph or sentence.
Inline links are underlined by default — they meet WCAG 1.4.1 without relying on colour alone.
Override the underline style on inline links to match the surrounding text.
Removing the underline from inline links makes them indistinguishable from surrounding text for colour-blind users.
Use variant='external' for any link leaving the kuoni.co.uk domain.
The external icon and rel='noreferrer noopener' are added automatically — no manual configuration needed.
Open third-party links in the same tab without warning users.
Opening external links in the same tab removes the Back button navigation — users lose their place on the site.
Use disabled with a clear reason visible in the surrounding content.
A disabled Link with surrounding copy ('This departure is fully booked') explains why the link is inactive.
Disable a link without providing any context about why it is unavailable.
A greyed-out link with no explanation forces users to guess why they cannot navigate.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| href | string | '#' | The destination URL. Removed when disabled is true. |
| children* | ReactNode | — | The visible link label. Should describe the destination or action. |
| variant | 'inline' | 'standalone' | 'external' | 'inline' | Visual treatment. inline=always underlined; standalone=underline on hover; external=underlined + icon + new tab. |
| color | 'teal' | 'dark' | 'teal' | Text colour. teal for interactive links; dark for navigation-style links. |
| disabled | boolean | false | Removes href, sets tabIndex=-1 and aria-disabled. Link is visible but non-interactive. |
| target | string | '_blank' for external variant | Forwarded to <a>. Defaults to _blank for external variant. |
| rel | string | 'noreferrer noopener' when target=_blank | Forwarded to <a>. Added automatically for external links. |
| className | string | — | Additional Tailwind classes on the anchor element. |
Accessibility
WCAG 1.4.1 — Use of colour
Inline links are underlined by default. This ensures they are distinguishable from surrounding text without relying on colour alone. Do not remove this underline from inline links.
Standalone links (outside body copy) may omit the underline at rest because their position in the layout (navigation, footer) already implies interactivity.
Visited state
The :visited pseudo-class changes the link colour to teal-700. This is intentional: on a travel site, knowing which destinations you have already viewed is genuinely useful navigation context.
Keyboard interaction
| Key | Action |
|---|---|
Tab | Move focus to the link |
Enter | Follow the link |
Spacedoes not activate<a>elements — it scrolls the page. If users must activate the control withSpace, use a Button withonClickinstead.
External links
<KuoniLink href="https://www.abta.com" variant="external">
ABTA
</KuoniLink>
The external variant automatically adds:
target="_blank"— opens in a new tabrel="noreferrer noopener"— prevents the new tab from accessingwindow.opener<ExternalLink>icon labelled"(opens in new tab)"— warns screen reader users before they follow the link
Related components
- Button — use instead of Link whenever the interaction changes state or data rather than navigating to a URL. Button itself can render as an
<a>viahrefwhen it needs button styling for a navigational CTA.