Components
Footer
BetaThe site footer — a dark full-width section containing navigation columns, trust badges, social links, a newsletter strip, and a legal row.
Purpose
The Footer is a persistent site-wide element that anchors the bottom of every page. It serves three distinct functions: navigation (links to key destinations, holiday types, and site sections), trust-building (badges, ATOL, ABTA, contact details), and legal compliance (copyright, privacy policy, terms).
Usage
Use the Footer on:
- Every public-facing page of the site — it is a layout-level component, not a page-specific one, and pairs with Navigation as the bookends of the page
- Both authenticated and unauthenticated states (the content may differ)
The Footer is not suitable for:
- Inline page content — do not embed a footer in a card or modal
- Short utility pages such as login, checkout confirmation, or error pages, where a simpler footer without navigation columns is preferred
Anatomy
Destinations
Africa
Asia
Indian Ocean
Holiday Types
Luxury Hotels
Safari
Beach Holidays
- 1Newsletter strip — Optional top band with a heading, description, and an email input + Subscribe button. Only renders when newsletterHeading is provided.
- 2Navigation columns — Responsive grid of link columns. Each column has an optional heading and an array of links. A column with contact={true} renders the phone number and email address instead of links.
- 3Trust badges — A row of bordered boxes, each containing an icon and a label. Communicates ATOL, ABTA, and other accreditations.
- 4Social links — Circular icon buttons for Facebook, Instagram, Twitter/X, and YouTube. Each has an accessible label.
- 5Legal row — Bottom strip with copyright text on the left and legal links (Privacy Policy, Terms, etc.) on the right. Separated from the main footer body by a top border.
Variants
With newsletter strip
When newsletterHeading is provided, a teal-bordered newsletter band renders above the navigation columns. It contains the heading, an optional description, an email input, and a Subscribe button.
With trust badges
Trust badges reinforce credibility below the navigation columns. Each badge has a label; an optional icon can be passed as a ReactNode.
Four-column layout
Pass four column objects to trigger the four-column grid. The layout adapts automatically — two columns on mobile, four on desktop.
Best practices
Rely on the built-in responsive grid rather than overriding column widths with className. The component handles 2, 3, and 4-column layouts automatically.
Columns collapse to a single-column accordion on mobile, keeping the footer compact below 768px.
Set explicit widths on individual column objects or override the grid via className.
Hardcoded widths break the responsive grid and can cause columns to overflow on narrow viewports.
Use the contact column type for phone and email rather than embedding them as plain text in a links array.
A contact column with contact={true} always shows the current phoneNumber and email from props — a single source of truth.
Put the phone number as a link label in a regular column when a contact column type is available.
Hardcoded phone numbers in link labels get out of sync when the number changes — update one prop, not many columns.
Limit trust badges to six or fewer. Show the most recognisable accreditations (ATOL, ABTA) first.
Trust badges are compact by design — four across on desktop, two rows on mobile.
Pass more than eight trust badges. If you have many accreditations, consider showing only the primary ones in the footer.
More than six badges crowd the row and reduce the impact of each badge.
Always provide a label for each social link (e.g. 'Kuoni on Facebook'). The icon alone is aria-hidden.
Social links provide an accessible label for screen readers and a recognisable icon for sighted users.
Pass social links without a label prop, leaving the icon as the only affordance.
An icon with no accessible label is invisible to screen reader users.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| columns | Array<{ heading?: string; logo?: string; links?: Array<{ label: string; href: string }>; contact?: boolean }> | [] | Navigation columns. Each column can have a heading, an array of links, or contact={true} to render the phone and email instead of links. Supports 2, 3, or 4 columns. |
| trustBadges | Array<{ label: string; icon?: ReactNode }> | — | Accreditation badges rendered in bordered boxes below the navigation columns. Each badge shows an optional icon and a text label. |
| socialLinks | Array<{ platform: 'facebook' | 'instagram' | 'twitter' | 'youtube'; href: string; label?: string }> | — | Social media links rendered as circular icon buttons. platform maps to the correct icon. label is used as aria-label on the button. |
| newsletterHeading | string | — | When provided, a newsletter subscription strip renders above the navigation columns with this heading, an email input, and a Subscribe button. |
| newsletterDescription | string | — | Optional subtitle below the newsletter heading. Displayed when newsletterHeading is also set. |
| legalLinks | Array<{ label: string; href: string }> | [] | Links in the bottom legal row — typically Privacy Policy, Cookie Policy, Terms and Conditions, and ABTA. |
| copyrightText | string | — | Copyright notice rendered on the left of the legal row. Example: "© 2025 Kuoni Travels Ltd." |
| phoneNumber | string | '0800 092 4444' | Phone number shown in contact columns and optionally in the trust area. Override when localising for non-UK markets. |
| string | — | Email address shown in contact columns as a mailto link. | |
| className | string | — | Additional CSS classes on the root footer element. |
Accessibility
Landmark role
The Footer renders as a <footer> element, which carries the implicit ARIA landmark role contentinfo. Screen readers expose it as "content info" in the landmarks list, allowing users to jump directly to it.
<footer aria-label="Site footer">
{/* columns, badges, legal row */}
</footer>
Navigation columns
Each column group is wrapped in a <nav> element with an aria-label matching the column heading. This creates separate landmarks for each link group:
<nav aria-label="Destinations">
<ul>
<li><a href="/africa">Africa</a></li>
<li><a href="/asia">Asia</a></li>
</ul>
</nav>
Newsletter form
The newsletter strip renders a <form>. The email input has an associated <label> (visually hidden if necessary). The Subscribe button is type="submit".
<form aria-label="Newsletter subscription">
<label htmlFor="footer-email">Email address</label>
<input id="footer-email" type="email" required />
<button type="submit">Subscribe</button>
</form>
Social links
Each social link button has an aria-label that describes its destination:
<a href="https://facebook.com/kuoni" aria-label="Kuoni on Facebook">
<FacebookIcon aria-hidden="true" />
</a>
Keyboard interaction
| Key | Action |
|---|---|
Tab | Moves through all interactive elements: nav links, social buttons, newsletter input, Subscribe button, legal links |
Enter | Follows the focused link or activates the focused button |
Space | Activates the focused button (Subscribe) |
Colour contrast
All text on the dark (bg-kuoni-dark) background meets WCAG AA contrast. The grey text hierarchy — text-grey-300 for headings, text-grey-400 for links, text-grey-500 for secondary — is pre-validated. Do not reduce these values.
Related components
- Navigation — the top-of-page counterpart to Footer; together they bookend every page.