KKUONIDesign System

Components

Link

Beta

Styled 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

  1. 1
    Anchor elementNative <a> with href, target, and rel. The component never strips these attributes.
  2. 2
    Text contentThe visible link label. Sentence-case, specific enough to make sense out of context.
  3. 3
    External iconExternalLink icon (14 px) from lucide-react. Only shown for the external variant. Labelled "(opens in new tab)" for screen readers.
  4. 4
    Focus ring2 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

StateAppearance
DefaultTeal (#005B55), underlined (inline) or plain (standalone)
HoverTeal-700 (#003D39), underlined (all variants)
VisitedTeal-700 (#003D39) — signals previously viewed destinations
Focus2 px teal ring, 2 px offset
Disabled40% opacity, pointer-events removed, tabIndex=-1

Best practices

Do

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.

Don't

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.

Do

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.

Don't

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.

Do

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.

Don't

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.

Do

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.

Don't

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

PropTypeDefaultDescription
hrefstring'#'The destination URL. Removed when disabled is true.
children*ReactNodeThe 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.
disabledbooleanfalseRemoves href, sets tabIndex=-1 and aria-disabled. Link is visible but non-interactive.
targetstring'_blank' for external variantForwarded to <a>. Defaults to _blank for external variant.
relstring'noreferrer noopener' when target=_blankForwarded to <a>. Added automatically for external links.
classNamestringAdditional 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

KeyAction
TabMove focus to the link
EnterFollow the link

Space does not activate <a> elements — it scrolls the page. If users must activate the control with Space, use a Button with onClick instead.

<KuoniLink href="https://www.abta.com" variant="external">
  ABTA
</KuoniLink>

The external variant automatically adds:

  • target="_blank" — opens in a new tab
  • rel="noreferrer noopener" — prevents the new tab from accessing window.opener
  • <ExternalLink> icon labelled "(opens in new tab)" — warns screen reader users before they follow the link
  • 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> via href when it needs button styling for a navigational CTA.