Footer

Site footer with social media bar and multi-column link grid with alternating column widths

Installation

pnpm add @wandercom/design-system-web

Usage

The Footer component provides a comprehensive site footer with social media links, multi-column navigation, and branding. It supports both standard WanderOS and individual property sites through its variant system.

26 lines
import { Footer } from '@wandercom/design-system-web/blocks/footer';
import { Logo } from '@wandercom/design-system-web/ui/logo';

export function Example() {
  return (
    <Footer
      topBar={{
        title: 'Follow us',
        links: [
          {
            label: 'X (Twitter)',
            href: 'https://x.com/wander',
            isExternal: true,
          },
        ],
      }}
      sections={[
        {
          title: 'Company',
          links: [{ label: 'About', href: '/about' }],
        },
      ]}
      logo={<Logo className="h-10 w-auto text-primary" />}
    />
  );
}

Example

The default footer variant includes trademark and copyright sections at the bottom and multi-column navigation. The Sites variant below is the documented social icon example.

Loading example...
79 lines
<Footer
  topBar={{
    title: 'Follow us',
    links: [
      {
        label: 'X (Twitter)',
        href: 'https://x.com/wander',
        isExternal: true,
      },
      {
        label: 'Instagram',
        href: 'https://instagram.com/wander',
        isExternal: true,
      },
      {
        label: 'TikTok',
        href: 'https://tiktok.com/@wander',
        isExternal: true,
      },
      {
        label: 'LinkedIn',
        href: 'https://linkedin.com/company/wander',
        isExternal: true,
      },
      {
        label: 'YouTube',
        href: 'https://youtube.com/@wander',
        isExternal: true,
      },
    ],
  }}
  sections={[
    {
      title: 'Company',
      links: [
        { label: 'About', href: '/about' },
        { label: 'Blog', href: '/blog' },
        { 
          label: 'Contact', 
          key: 'contact',
          onClick: () =>
            toast.success({
              label: "Copied to clipboard",
              description: "Contact information copied",
            }),
        },
        { label: 'Careers', href: '/careers' },
        { label: 'Store', href: '/store' },
      ],
    },
    {
      title: 'Resources',
      links: [
        { label: 'Locations', href: '/locations' },
        { label: 'Licensing', href: '/licensing' },
        { label: 'Terms', href: '/terms' },
        { label: 'Privacy', href: '/privacy' },
        { label: 'Sitemap', href: '/sitemap' },
        { label: 'Events', href: '/events' },
      ],
    },
    {
      title: 'Hosts',
      links: [
        { label: 'WanderOS', href: '/sites' },
        { label: 'Operate with us', href: '/operate' },
        { label: 'List with us', href: '/listed' },
      ],
    },
    {
      title: 'Partners',
      links: [
        { label: 'Ambassadors', href: '/ambassadors' },
        { label: 'Travel Agents', href: '/travelagents' },
      ],
    },
  ]}
  logo={<Logo className="h-10 w-auto text-primary" />}
/>

Variants

The Footer component supports two variants optimized for different use cases.

Default variant

The default variant is designed for main Wander marketing and application sites. It features trademark and copyright sections at the bottom, and uses an alternating column width pattern for visual interest.

Sites variant

The Sites variant is optimized for individual property site footers. It replaces the trademark/copyright section with "Powered by WanderOS" branding, uses a custom 2-2-4 column span pattern for sections, and contains the social icon example. The icons below come from Central Icons, but consumers may pass any React icon node. For icon links, label supplies the accessible name and is visually hidden.

Loading example...
85 lines
import { IconInstagram } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconInstagram';
import { IconLinkedin } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconLinkedin';
import { IconTiktok } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconTiktok';
import { IconX } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconX';
import { IconYoutube } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconYoutube';

<Footer
  variant="sites"
  logo={<WanderOSLogo className="h-10 w-auto text-primary" />}
  topBar={{
    title: 'Follow us',
    links: [
      {
        label: 'X (Twitter)',
        href: 'https://x.com/wander',
        isExternal: true,
        icon: <IconX className="size-5" />,
      },
      {
        label: 'Instagram',
        href: 'https://instagram.com/wander',
        isExternal: true,
        icon: <IconInstagram className="size-5" />,
      },
      {
        label: 'TikTok',
        href: 'https://tiktok.com/@wander',
        isExternal: true,
        icon: <IconTiktok className="size-5" />,
      },
      {
        label: 'LinkedIn',
        href: 'https://linkedin.com/company/wander',
        isExternal: true,
        icon: <IconLinkedin className="size-5" />,
      },
      {
        label: 'YouTube',
        href: 'https://youtube.com/@wander',
        isExternal: true,
        icon: <IconYoutube className="size-5" />,
      },
    ],
  }}
  sections={[
    {
      title: 'Company',
      links: [
        { label: 'About', href: '/about' },
        { label: 'List with us', href: '/list' },
        { label: 'Contact', href: '/contact' },
        { label: 'Property manager portal', href: '/property-manager' },
        { label: 'Owner portal', href: '/owner-portal' },
      ],
    },
    {
      title: 'Resources',
      links: [
        {
          label: 'Activities in Northern Kentucky',
          href: '/northern-kentucky',
        },
        { label: 'Activities in Nashville', href: '/nashville' },
        { label: 'Sitemap', href: '/sitemap' },
        { label: 'Terms of service', href: '/terms' },
        { label: 'Privacy policy', href: '/privacy' },
      ],
    },
    {
      title: 'Contact us',
      links: [
        { label: 'Send us a message', href: '/message' },
        {
          label: 'info@downtimevacationrentals.com',
          href: 'mailto:info@downtimevacationrentals.com',
        },
        { label: '603-770-9939', href: 'tel:6037709939' },
        {
          label: '219 Surfside DR, Myrtle Beach, South Carolina',
          href: 'https://maps.google.com/?q=219+Surfside+DR,+Myrtle+Beach,+SC',
        },
      ],
    },
  ]}
/>

The Footer component supports two types of links to accommodate different interaction patterns.

Most footer links use the href prop to navigate to pages. For external links, set isExternal: true to add proper security attributes. Top bar links may pass any consumer-provided icon node; when icon is present, its label becomes the accessible name instead of visible text. The Sites example demonstrates this pattern with Central Icons.

7 lines
{ label: 'Privacy', href: '/privacy' }
{
  label: 'Instagram',
  href: 'https://instagram.com/wander',
  isExternal: true,
  icon: <IconInstagram className="size-5" />,
}

For links that trigger actions instead of navigation (like copying to clipboard), use the onClick pattern. When using onClick, you must provide a unique key prop.

5 lines
{
  label: 'Contact',
  key: 'contact',
  onClick: () => toast.success({ label: 'Copied!' })
}

Layout

The footer uses a responsive Grid layout with different patterns for each variant:

Default variant:

  • Mobile (base): All sections span full width and stack vertically
  • Tablet (md): Sections alternate between 2 and 4 columns for visual rhythm (1st: 2 cols, 2nd: 4 cols, 3rd: 2 cols, 4th: 4 cols)
  • Desktop (lg): All sections span 2 columns within a 12-column grid

Sites variant:

  • Custom column span pattern: 2-2-4 (first section: 2 cols, second: 2 cols, third: 4 cols)

The logo section always spans full width on mobile and 4 columns on desktop, remaining unaffected by section span patterns.

Props

variant?:

"default" | "sites"
Visual variant of the footer. The default variant displays trademark and copyright sections and uses alternating column widths. The sites variant displays "Powered by WanderOS" branding and uses a 2-2-4 column span pattern.

topBar?:

{ title?: string; links?: LinkItem[] }
Top bar configuration for social media links. Consumer-provided icons replace visible link labels while preserving accessible names.

sections?:

LinkSection[]
Array of navigation sections displayed as columns. Each section includes a title and array of links. Supports up to 4 sections in the default variant. Column spans vary by variant and breakpoint.

logo?:

React.ReactNode
Logo content displayed in the first column of the footer grid. Typically the Logo component or WanderOSLogo, but can be any React node including images or SVGs.

trademark?:

string
Trademark text displayed at the bottom of the footer (default variant only). Will have the registered trademark symbol appended.

className?:

string
Additional CSS classes to apply to the footer container.

LinkItem

label:

string
Display text for a navigation link, or the accessible name when an icon is used in the top bar.

href?:

string
URL the link navigates to. Use this for standard navigation links. Either href or onClick with key is required.

onClick?:

function
Function to call when the link is clicked. Use this for interactive links that trigger actions instead of navigation. When using onClick, you must provide a unique key prop.

onKeyPress?:

function
Function to call when a key is pressed while the link is focused. Only used with onClick links for keyboard accessibility.

key?:

string | number
Unique identifier for the link. Required when using onClick, optional when using href (defaults to href value).

isExternal?:

boolean
Indicates the link opens an external site. When true, automatically adds target="_blank" and rel="noopener noreferrer" for security. Use this for social media links and external resources.

icon?:

React.ReactNode
Consumer-provided icon. In topBar links, it replaces visible text while the label remains available to assistive technology.
Footer