Footer is a page footer built as a compound component. It is composed from: Footer, FooterContent, FooterLeft, FooterLogo, FooterLeftText, FooterRight, FooterNavHeading, FooterNavLink, and FooterMeta.
Usage
Arrange branding in FooterLeft, links in FooterRight, and the copyright line in FooterMeta. FooterMeta is a sibling of FooterContent, not a child. It renders as the bottom row of the footer, beneath the content row.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import {
Footer,
FooterContent,
FooterLeft,
FooterRight,
FooterMeta,
Button,
} from "@e-infra/design-system";
import { EInfraLogo } from "./einfra-logo";
<Footer>
<FooterContent>
<FooterLeft>
<FooterLogo>
<EInfraLogo />
</FooterLogo>
<FooterLeftText>Operated by CERIT-SC, ICS MUNI</FooterLeftText>
</FooterLeft>
<FooterRight>
<Button variant="ghost" size="sm" asChild>
<a href="#">
<span>Privacy Policy</span>
</a>
</Button>
<Button variant="ghost" size="sm" asChild>
<a href="#" target="_blank" rel="noopener noreferrer">
<span>Documentation</span>
</a>
</Button>
</FooterRight>
</FooterContent>
<FooterMeta
copyright={`Copyright © ${new Date().getFullYear().toString()} e-INFRA CZ`}
/>
</Footer>;
Logo and left text
FooterLogo and FooterLeftText are optional children of FooterLeft. FooterLogo is a plain container for a custom logo, and FooterLeftText renders a muted caption beneath it. Give FooterLeft a column layout to stack them.
<FooterLeft className="flex-col items-start gap-2">
<FooterLogo>
<img src="/einfra-logo.svg" alt="e-INFRA CZ" className="h-12 w-auto" />
</FooterLogo>
<FooterLeftText>Operated by CERIT-SC and ICS MUNI</FooterLeftText>
</FooterLeft>
Navigation link lists
FooterRight can hold grouped navigation. FooterNavHeading labels each column with muted uppercase text, and FooterNavLink renders links that underline on hover. Wrap each group in a nav with a column layout.
<FooterRight className="items-start gap-8 md:gap-12">
<nav className="flex flex-col gap-2">
<FooterNavHeading>Resources</FooterNavHeading>
<FooterNavLink href="/docs">Documentation</FooterNavLink>
<FooterNavLink href="/status">Status</FooterNavLink>
</nav>
<nav className="flex flex-col gap-2">
<FooterNavHeading>Legal</FooterNavHeading>
<FooterNavLink href="/privacy">Privacy Policy</FooterNavLink>
<FooterNavLink href="/terms">Terms of Service</FooterNavLink>
</nav>
</FooterRight>
Copyright
FooterMeta takes an optional copyright node and wraps it in a paragraph. There is no default owner and no automatic year, so pass the full string you want rendered.
<FooterMeta
copyright={`Copyright © ${new Date().getFullYear().toString()} e-INFRA CZ — All rights reserved.`}
/>
Omit copyright to render children instead. This is the way to put a version string, build metadata, or extra links in the bottom row. The row is a justify-between flex container, so two children sit at opposite ends.
<FooterMeta>
<p className="text-sm text-text-muted">Copyright © ${new Date().getFullYear().toString()} e-INFRA CZ</p>
<span className="text-sm text-text-muted">v1.0.0</span>
</FooterMeta>
copyright wins when both are supplied — children are ignored.
FooterContent and FooterMeta each constrain their width to the container max-width. Opt out of both to span the viewport.
<Footer>
<FooterContent container={false}>{/* ... */}</FooterContent>
<FooterMeta container={false} copyright="Copyright © ${new Date().getFullYear().toString()} e-INFRA CZ" />
</Footer>
Components
| Component | Description |
|---|
Footer | Root element rendered as footer |
FooterContent | Inner flex container with optional width constraint |
FooterLeft | Left-aligned row for branding and descriptive copy |
FooterLogo | Optional container for a custom logo inside FooterLeft |
FooterLeftText | Optional muted caption rendered beneath FooterLogo |
FooterRight | Right-aligned row for links and actions |
FooterNavHeading | Uppercase, muted heading that labels a nav column |
FooterNavLink | Muted link that underlines on hover |
FooterMeta | Bottom row for the copyright line and other metadata |
Props
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLElement> | - | Native footer props |
| Prop | Type | Default | Description |
|---|
| container | boolean | true | Whether to constrain width to the container max-width |
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLParagraphElement> | - | Native p props |
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLHeadingElement> | - | Native h3 props |
| Prop | Type | Default | Description |
|---|
| className | string | - | Additional CSS classes |
| ...props | React.AnchorHTMLAttributes<HTMLAnchorElement> | - | Native a props |
| Prop | Type | Default | Description |
|---|
| copyright | React.ReactNode | - | Copyright node, rendered in a muted p instead of children |
| container | boolean | true | Whether to constrain width to the container max-width |
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
Structure
| Part | Details |
|---|
| Outer wrapper | footer with w-full border-t border-border bg-background |
| Content row | flex flex-col gap-4 px-4 py-6 md:flex-row md:items-center md:gap-6 |
| Left section | flex items-center gap-4 md:gap-6 for branding and copy |
| Right section | flex items-center gap-2 md:ml-auto for links and actions |
| Meta row | flex flex-col items-center justify-between gap-2 px-4 pb-6 sm:flex-row |
Behavior
| Behavior | Details |
|---|
| Composition-first API | Layout is built by arranging the subcomponents rather than selecting from variants |
| Width control | FooterContent and FooterMeta each constrain width and opt out with container={false} |
| Copyright shorthand | FooterMeta renders copyright when given, and falls back to children when it is omitted |
| Responsiveness | The content row stacks at md: and the meta row at sm:, centering their content |
| Custom styling | Native className props allow local overrides without changing the implementation |