SearchCtrlK

  • ↑↓navigate
  • ↵open
  • escclose

Can’t find it? Contact us

SiteFooter

Site footer for landing and product pages.

Open in a new tab
View code
tsx
<SiteFooter
	brand={<a href="/" aria-label="Keel home"><KeelLogo /></a>}
	tagline="Usage-based billing for API companies, from the first metered event to the paid invoice."
	newsletter={
		<form action="/newsletter" method="post">
			<label>
				<span mix={[visuallyHidden()]}>Email address</span>
				<Input type="email" name="email" placeholder="you@company.com" required />
			</label>
			<Button type="submit" color="neutral">Subscribe</Button>
		</form>
	}
	columns={[
		{ title: "Product", links: [{ label: "Metering", href: "/metering" }, …] },
		{ title: "Developers", links: […] },
		{ title: "Company", links: […] },
		{ title: "Resources", links: […] },
		{ title: "Legal", links: […] },
	]}
	social={
		<>
			<a href="/community" aria-label="Community forum"><MessagesSquareIcon /></a>
			<a href="/feed.xml" aria-label="RSS feed"><RssIcon /></a>
			<a href="mailto:hello@keel.dev" aria-label="Email us"><MailIcon /></a>
		</>
	}
	legal={
		<>
			<p>© 2026 Keel, Inc.</p>
			<a href="/privacy">Privacy</a>
			<a href="/terms">Terms</a>
		</>
	}
	wordmark={<KeelWordmark />}
/>

Demo landings

Whole pages built only from @sdxc/ui, each for an invented product with its own palette and type. They open in a new tab.

Every demo, landings and docs sites alike, is listed in the demo gallery.

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

Terminal
npm add @sdxc/ui remix
typescript
import "@sdxc/ui/theme.css";

Usage

typescript
import { SiteFooter } from "@sdxc/ui/landing";

Renders the page footer: a measured column holding an optional newsletter band, the brand block beside or above the link columns, the legal row, then the wordmark. Column counts per row derive from columns.length at every container step, so 3 or 5 columns never strand one alone on a row.

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

PropTypeRequiredDescription
brandRemixNodeNoThe brand mark, usually a home link wrapping the logo.
taglineRemixNodeNoOne or two lines under the brand mark in the muted ink.
columnsColumn[]YesLink columns; any count lays out without a short last row.
newsletterRemixNodeNoA newsletter form the page supplies, placed by newsletterPlacement.
newsletterPlacement"column" | "band"NoDefaults to DEFAULT_NEWSLETTER_PLACEMENT.
socialRemixNodeNoIcon links with an aria-label each. The footer sizes every direct child to a 1.25rem glyph inside a 44px hit area on a phone, 36px from the md container.
legalRemixNodeNoThe bottom row: copyright and legal links, with social at its inline end.
wordmarkRemixNodeNoA brand wordmark, usually an SVG, drawn full width in the brand ink as the last thing on the page and hidden from assistive technology.
labelRemixNodeNoVisually hidden heading naming the footer in the outline. Defaults to DEFAULT_LABEL.
levelHeadingLevelNoLevel of that hidden heading; column titles render one below it. Defaults to one below the ambient HeadingScope, so a footer on a bare page opens with <h2>.
ruledbooleanNoDraws the hairline along the footer's top edge. Defaults to true.
prefetchLinkPrefetchNoWhen the column links start loading their pages. Defaults to "none"; "intent" warms a destination as the visitor hovers or focuses it.

Also accepts everything in Omit<TagProps<"footer">, "children">.

Types

NameValuesWhat it decides
NewsletterPlacement"column" | "band"Where the newsletter slot sits: under the tagline in the brand block, or as a full band above the brand block and the columns.
@sdxc/ui

Can’t find it? Contact us