App Shell

Footer

An app footer with five Container-aligned areas, plus a companion FooterColumns grid of link groups with route-aware active links and an automatic external-link indicator. Completes the app shell together with Header and Main.

Basic Usage

The main row has left, center (children), and right areas. On mobile they stack with the right area first and the left (copyright) last; on lg they line up left to right.

Copyright 2026 Acme Inc.

<script lang="ts">
  import { Footer, Button } from 'sv5ui';
</script>

<Footer>
  {#snippet left()}
    <p>Copyright 2026 Acme Inc.</p>
  {/snippet}

  <!-- children render in the center area -->
  <nav class="flex items-center gap-4 text-sm">
    <a href="/docs">Docs</a>
    <a href="/blog">Blog</a>
  </nav>

  {#snippet right()}
    <Button icon="lucide:github" variant="ghost" color="surface" size="sm" />
    <Button icon="lucide:twitter" variant="ghost" color="surface" size="sm" />
  {/snippet}
</Footer>

Link Columns

Put FooterColumns in the footer's top snippet and pass a columns array. Links with target="_blank" get an external-link icon automatically, and the link matching the current route is highlighted (notice "Footer" in the App Shell column below).

<script lang="ts">
  import { Footer, FooterColumns } from 'sv5ui';
  import type { FooterColumn } from 'sv5ui';

  const columns: FooterColumn[] = [
    {
      label: 'Product',
      children: [
        { label: 'Components', href: '/docs/components' },
        { label: 'Hooks', href: '/docs/hooks' },
        { label: 'Changelog', href: '/changelog' }
      ]
    },
    {
      label: 'Community',
      children: [
        // target="_blank" links get the external icon automatically
        { label: 'GitHub', href: 'https://github.com/ndlabdev/sv5ui', target: '_blank' },
        { label: 'Discord', href: 'https://discord.gg', target: '_blank' }
      ]
    },
    {
      label: 'Legal',
      children: [
        { label: 'Privacy', href: '/privacy' },
        { label: 'Terms', href: '/terms' }
      ]
    }
  ];
</script>

<Footer>
  {#snippet top()}
    <FooterColumns {columns} />
  {/snippet}
  {#snippet left()}
    <p>Copyright 2026 Acme Inc.</p>
  {/snippet}
</Footer>

Route-aware Links

Every column link is a full sv5ui Link: it accepts all LinkProps and resolves active state against the current route. Style the states through the linkActive / linkInactive slots.

See the "App Shell" column in the demo above: the Footer link is highlighted because you are on this page.

<!-- Each column link is a full sv5ui Link: it resolves
     active state against the current route and styles it
     via the linkActive / linkInactive slots. -->
const columns: FooterColumn[] = [
  {
    label: 'Docs',
    children: [
      // Highlighted while you are on this page
      { label: 'Footer', href: '/docs/components/footer' },
      { label: 'Header', href: '/docs/components/header' }
    ]
  }
];

Side Sections

left and right snippets sit beside the grid on xl screens: brand blurb on the left, newsletter or call to action on the right.

<FooterColumns {columns}>
  {#snippet left()}
    <!-- Before the columns on xl screens -->
    <div>
      <p class="text-xl font-black">ACME</p>
      <p class="text-sm">Build Svelte apps faster.</p>
    </div>
  {/snippet}

  {#snippet right()}
    <!-- After the columns: newsletter / call to action -->
    <form class="flex gap-2">
      <Input placeholder="you@example.com" size="sm" />
      <Button label="Subscribe" size="sm" />
    </form>
  {/snippet}
</FooterColumns>

Custom Link Rendering

The link snippet replaces the default Link element per item, and columnLabel does the same for headings. Both receive the item being rendered.

Use this when a "link" is not a navigation (a cookie-settings trigger, for example).

<!-- Replace the default Link rendering per item -->
<FooterColumns {columns}>
  {#snippet link({ link })}
    <span class="inline-flex items-center gap-1 text-sm">
      {#if link.icon}<Icon name={link.icon} class="size-3.5" />{/if}
      {link.label}
    </span>
  {/snippet}
</FooterColumns>

Footer UI Slots

Use the `ui` prop to override classes on internal elements.

SlotDescription
rootThe `<footer>` element with a top border
topFull-width area above the main row, designed for FooterColumns
containerContainer-aligned main row. Stacks on mobile, three columns on `lg` and up
leftLeft area of the main row. Last in the mobile stack, first on `lg`
centerCenter area of the main row (the `children` snippet)
rightRight area of the main row. First in the mobile stack, last on `lg`
bottomFull-width area below the main row

Footer Props

Snippets: `top`, `left`, `children` (center), `right`, `bottom`.

PropTypeDefault
askeyof HTMLElementTagNameMap'footer'
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-

FooterColumns UI Slots

SlotDescription
rootThe `<nav>` element wrapping the grid
leftSide section before the columns on `xl` screens
centerThe columns grid
rightSide section after the columns on `xl` screens
columnOne column of links
labelColumn heading
list / itemLink list and list items
linkEach link element
linkActive / linkInactiveState classes applied by route matching
linkLeadingIconIcon before the link label
linkLabelExternalIconExternal indicator shown on `target="_blank"` links

FooterColumns Props

Snippets: `left`, `right`, `children` (extra grid column), `columnLabel`, `link`.

PropTypeDefault
columnsFooterColumn[]-
askeyof HTMLElementTagNameMap'nav'
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-

FooterColumnLink

Shape of each entry in a column's `children` array.

PropertyTypeDefault
labelstring-
iconstring-
...LinkPropsLinkProps-