Footer
Bottom area for links and meta content.
Footer Examples
Copy-ready examples with live previews.
Basic usage
The simplest footer: brand text + subtitle.
Live preview
Basic
import Footer from "@/_components/footer/Footer";
export default function Example() {
return (
<Footer
brandTitle="cssnt_components"
brandSubtitle="Material-ish components"
/>
);
}With navigation links
Use `links` to render a docs/navigation column. External links can opt-in via `external`.
Live preview
Links
import Footer from "@/packages/ui/src/_components/footer/Footer";
export default function Example() {
return (
<Footer
brandTitle="cssnt_components"
brandSubtitle="Material-ish components"
links={[
{ label: "Docs", href: "/docs" },
{ label: "Changelog", href: "/changelog" },
{ label: "GitHub", href: "https://github.com/...", external: true },
]}
/>
);
}With action buttons
Use `actionButtons` to render an actions column (only when `variant !== minimal).
• Action buttons accept any ReactNode: Button, Link-wrapped Button, anchors, etc.
Live preview
Actions
import Link from "next/link";
import Footer from "@/packages/ui/src/_components/footer/Footer";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<Footer
brandTitle="cssnt_components"
brandSubtitle="Material-ish components"
links={[
{ label: "Docs", href: "/docs" },
{ label: "Changelog", href: "/changelog" },
{ label: "GitHub", href: "https://github.com/...", external: true },
]}
actionButtons={[
<Link key="getting-started" href="/docs/getting-started">
<Button variant="primary" ripple variantRadio="sm">
Getting started
</Button>
</Link>,
<a key="github" href="https://github.com/..." target="_blank" rel="noreferrer">
<Button variant="transparent" ripple variantRadio="sm">
GitHub
</Button>
</a>,
]}
/>
);
}Variant and alignment
Use `variant` to control layout density and `align` to control horizontal alignment.
Live preview
Standard vs minimal
import Footer from "@/packages/ui/src/_components/footer/Footer";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "grid", gap: 14 }}>
<Footer
variant="standard"
align="start"
brandTitle="Standard / start"
brandSubtitle="Shows brand + links + actions (when provided)."
links={[
{ label: "Docs", href: "/docs" },
{ label: "GitHub", href: "https://github.com/...", external: true },
]}
actionButtons={[
<Button key="contact" variant="primary" ripple variantRadio="sm">
Contact
</Button>,
]}
/>
<Footer
variant="minimal"
align="center"
brandTitle="Minimal / center"
brandSubtitle="Minimal disables the actions column."
links={[
{ label: "Docs", href: "/docs" },
{ label: "GitHub", href: "https://github.com/...", external: true },
]}
actionButtons={[
<Button key="hidden" variant="primary" ripple variantRadio="sm">
(Hidden)
</Button>,
]}
/>
</div>
);
}Custom bottom bar
Override `bottomLeft` to customize the footer bar text.
Live preview
Custom bottomLeft
import Footer from "@/packages/ui/src/_components/footer/Footer";
export default function Example() {
const year = new Date().getFullYear();
return (
<Footer
brandTitle="cssnt_components"
brandSubtitle="Material-ish components"
links={[
{ label: "Docs", href: "/docs" },
{ label: "GitHub", href: "https://github.com/...", external: true },
]}
bottomLeft={
<span style={{ display: "inline-flex", gap: 8, alignItems: "center" }}>
<span>© {year}</span>
<span style={{ opacity: 0.75 }}>CSSN'T</span>
</span>
}
/>
);
}Playground
Quickly validate combinations and edge cases in a single place.
Live preview
Interactive playground
import { useState } from "react";
import Link from "next/link";
import Footer from "@/_components/footer/Footer";
import { Button } from "@/_components/buttons_variants/buttons/Button";
export default function Example() {
const [variant, setVariant] = useState<"standard" | "minimal">("standard");
const [align, setAlign] = useState<"start" | "center">("start");
const [showLogo, setShowLogo] = useState(true);
const [useLongLinks, setUseLongLinks] = useState(false);
const links = useLongLinks
? [
{ label: "Docs", href: "/docs" },
{ label: "Components", href: "/components" },
{ label: "Tokens", href: "/tokens" },
{ label: "Changelog", href: "/changelog" },
{ label: "Roadmap", href: "/roadmap" },
{ label: "GitHub", href: "https://github.com/...", external: true },
]
: [
{ label: "Docs", href: "/docs" },
{ label: "Changelog", href: "/changelog" },
{ label: "GitHub", href: "https://github.com/...", external: true },
];
return (
<div style={{ display: "grid", gap: 12 }}>
<div style={{ display: "flex", flexWrap: "wrap", gap: 8, alignItems: "center" }}>
<Button
variant="primary"
ripple
variantRadio="sm"
onClick={() => setVariant(v => (v === "standard" ? "minimal" : "standard"))}
>
Variant: {variant}
</Button>
<Button
variant="transparent"
ripple
variantRadio="sm"
onClick={() => setAlign(a => (a === "start" ? "center" : "start"))}
>
Align: {align}
</Button>
<Button
variant="transparent"
ripple
variantRadio="sm"
onClick={() => setShowLogo(v => !v)}
>
Logo: {showLogo ? "on" : "off"}
</Button>
<Button
variant="transparent"
ripple
variantRadio="sm"
onClick={() => setUseLongLinks(v => !v)}
>
Links: {useLongLinks ? "long" : "basic"}
</Button>
</div>
<Footer
variant={variant}
align={align}
showLogo={showLogo}
brandTitle={
<span style={{ display: "inline-flex", gap: 8, alignItems: "baseline" }}>
<span>cssnt_components</span>
<span style={{ opacity: 0.65, fontSize: 12 }}>v1.0</span>
</span>
}
brandSubtitle="Tweak variant/align/logo and validate layout."
links={links}
actionButtons={[
<Link key="docs" href="/docs">
<Button variant="primary" ripple variantRadio="sm">
Docs
</Button>
</Link>,
<a key="repo" href="https://github.com/..." target="_blank" rel="noreferrer">
<Button variant="transparent" ripple variantRadio="sm">
Repository
</Button>
</a>,
]}
bottomLeft="© cssnt_components"
/>
</div>
);
}On this page
Footer Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| className | string | No | undefined | Extra class names for the <footer> root. |
| customStyles | React.CSSProperties | No | undefined | Inline styles for the <footer> root. |
| variant | "standard" | "minimal" | No | "standard" | Layout density. "minimal" reduces columns and disables the actions column. |
| align | "start" | "center" | No | "start" | Alignment class applied to the root. |
| showLogo | boolean | No | true | Toggles the brand logo rendering. |
| logoSrc | string | No | "/images/cssnt_logo.png" | Brand logo source. |
| logoAlt | string | No | "Logo" | Brand logo alt text. |
| logoSize | string | No | "72px" | Brand logo size (passed as height/width to Image). |
| brandTitle | React.ReactNode | string | No | undefined | Brand text (rendered as a Title h3). |
| brandSubtitle | React.ReactNode | string | No | undefined | Brand subtitle (rendered as a Paragraph). |
| links | Array<{ label: string; href: string; external?: boolean }> | No | [] | Navigation links. Renders a "Documentation" column when non-empty. |
| actionButtons | React.ReactNode[] | No | [] | Custom nodes. Renders an "Extras" column when non-empty and variant !== "minimal". |
| bottomLeft | React.ReactNode | No | "© current year" | Bottom-left content for the footer bar. Defaults to © current year. |
| bottomRight | React.ReactNode | No | undefined | Declared in types but not currently rendered by Footer.tsx (no effect today). |