Site Footer
FreePremium multi-column marketing / commerce footer: a brand block (logo, tagline, socials), configurable link columns, an optional newsletter signup, and a bottom bar with copyright, legal links and payment chips. Default, minimal and always-dark variants.
</>sv-site-footer footerlayoutnavigationnewsletterecommerce
import { SvSiteFooterComponent } from '@styloviz/layout';Demo & usage
Basic usage
Usage example — open the gallery for the full interactive demo.
An interactive demo for this component lives in the gallery.
Open live demoMore examples
With newsletter + payments
example.htmlAngular
9 lines
<sv-site-footer brandName="Styloviz" tagline="Elegant components for storefronts." [columns]="columns" [socials]="socials" [legalLinks]="legal" [payments]="payments" [newsletter]="true" (subscribe)="subscribe($event)" />
Always-dark variant
example.htmlAngular
1 lines
<sv-site-footer variant="dark" brandName="Styloviz" [columns]="columns" />
Minimal (single row)
example.htmlAngular
1 lines
<sv-site-footer variant="minimal" brandName="Styloviz" [legalLinks]="legal" [socials]="socials" />
Newsletter request state + external links
example.htmlAngular
19 lines
<sv-site-footer brandName="Styloviz" [columns]="columns" [socials]="socials" [newsletter]="true" [newsletterStatus]="status()" [newsletterMessage]="message()" externalTarget="_blank" navLabel="Shop" legalNavLabel="Policies" (subscribe)="subscribe($event)" /> // subscribe(email: string) { // this.status.set('pending'); // this.api.subscribe(email).subscribe({ // next: () => { this.message.set('Check your inbox to confirm.'); this.status.set('success'); }, // error: (e) => { this.message.set(e.message); this.status.set('error'); }, // }); // }
When to use
- The global footer of a storefront, marketing site or dashboard-adjacent public page.
- You want link columns plus a newsletter capture and trust signals (payments, legal) in one block.
- Use the minimal variant for app-shell footers where a full sitemap would be too heavy.
Async states
None — this component has nothing to load, so it has no loading, empty or error state to drive.
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| brandName | string | '' | Brand name shown in the brand block / bottom bar. |
| logoSrc | string | '' | Optional brand logo image URL. |
| tagline | string | '' | Short tagline under the brand. |
| columns | readonly FooterColumn[] | [] | Link columns. |
| socials | readonly FooterSocial[] | [] | Social icon links; `iconName` names a glyph in `@styloviz/icons`. |
| newsletter | boolean | false | Show the newsletter signup block. |
| newsletterTitle | string | 'Stay in the loop' | Newsletter heading. |
| newsletterText | string | 'Subscribe for new arrivals, exclusive … | Newsletter supporting text. |
| newsletterPlaceholder | string | 'Enter your email' | Newsletter input placeholder. |
| newsletterCta | string | 'Subscribe' | Newsletter submit label. |
| legalLinks | readonly FooterLegalLink[] | [] | Legal links in the bottom bar. |
| payments | readonly FooterPayment[] | [] | Payment method chips. |
| copyright | string | '' | Copyright line. Auto-generated from brand + current year when empty. |
| variant | SiteFooterVariant | 'default' | Visual variant. |
| newsletterStatus | SiteFooterNewsletterStatus | 'idle' | Where the host's newsletter request is: `idle`, `pending`, `success` or `error`. While `pending` the field is read-only, the button is `aria-disabled` (not `disabled`, which would strand the keyboard focus the user submitted from) and a second submit is ignored; `success`/`error` are announced politely. Leave it unbound and the footer behaves exactly as before — `subscribe` fires and the field clears. |
| newsletterMessage | string | '' | The text announced for the current `newsletterStatus` — typically the server's own reason on `error`. Empty uses a short built-in message. |
| footerLabel | string | 'Site footer' | Accessible name of the `<footer>` landmark itself. |
| navLabel | string | 'Footer' | Accessible name of the link-columns `<nav>`. Every `<nav>` on a page needs a DISTINCT name, or a screen-reader landmark list shows two identical entries — so if the page header already has a nav called "Footer" (unlikely) or you render two footers, rename it here. |
| legalNavLabel | string | 'Legal' | Accessible name of the legal-links `<nav>`. Must differ from `navLabel`; a dev-mode warning fires when they match. |
| externalTarget | SiteFooterLinkTarget | '_self' | How links to ANOTHER origin open — social links and any absolute `http(s)` column or legal link. `_blank` adds a visually-hidden "(opens in a new tab)" to the name. Either way an external link always carries `rel="noopener noreferrer"`, and any `href` with an unsafe scheme (`javascript:`, `data:`, `vbscript:`) is dropped rather than rendered. |
| newTabLabel | string | '(opens in a new tab)' | Suffix appended to an external link's accessible name when `externalTarget` is `_blank`. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| linkSelect | FooterLink | Emitted when a column / navigation link is activated (an in-app href is also routed through `SV_LINK_ADAPTER` — don't navigate again from here when the app provides one) — and when a legal link with no rendered `href` (none given, or dropped by the URL policy) is activated, so the host can route it. A legal link WITH an href navigates natively and emits nothing, as before. |
| subscribe | string | Emitted with the email when the newsletter form is submitted. |
Customization & theming
- Brand block with optional logo, tagline and social icons.
- Any number of link columns, each link with an optional badge.
- Optional newsletter block (title / text / placeholder / CTA all configurable).
- Bottom bar with legal links and payment chips; default / minimal / dark variants.
- Newsletter request state: `newsletterStatus` (`idle` | `pending` | `success` | `error`) plus `newsletterMessage`. Leave it unbound and `subscribe` behaves exactly as before.
- Landmark names: `footerLabel`, `navLabel`, `legalNavLabel`.
- External-link policy: `externalTarget` (`_self` | `_blank`) and `newTabLabel`.
- Variant axes (X-8): `variant` is the only APPEARANCE axis (default / minimal / dark). `newsletter`, `newsletterStatus` and `externalTarget` are BEHAVIOURAL. Known limits: `minimal` renders brand, legal links, socials and copyright only — `columns`, `tagline`, `payments` and the newsletter are not shown in it; `dark` ignores the page theme by design.
Best practices
- Do: Group links into 2–4 short columns with clear headings.
- Do: Handle `subscribe` to POST the email; the field clears itself on submit.
- Do: Leave `copyright` empty to auto-generate "© {year} {brand}" — it always stays current.
- Tip: Use `variant="dark"` for a premium dark footer on an otherwise light page — it does not depend on the page theme.
- Don't: Don't overload it — move a full sitemap to a dedicated page and keep the footer scannable.
- Do: Drive `newsletterStatus` from your request: `pending` when you POST, then `success` or `error` with `newsletterMessage` set to the server's reason. On `error` the address the user typed is put back so they can fix it.
- Do: Rename `navLabel` / `legalNavLabel` (and `footerLabel`) when the page already has a nav with the same name, or when you render two footers — every landmark needs a distinct name.
- Tip: External links: every social link and every other-origin `http(s)` link gets `rel="noopener noreferrer"`. Set `externalTarget="_blank"` to open them in a new tab; the accessible name then says "(opens in a new tab)" (`newTabLabel`). Hrefs with an unsafe scheme (`javascript:`, `data:`, `vbscript:`) are dropped — only http(s), mailto, tel and relative URLs render.
- Tip: Layout (X-9): the footer is in normal flow — no scroll root, no portal, nothing measured. Breakpoints: link columns go 2 → 4 across at `sm`, the newsletter band splits in two at `md`, and the brand block sits beside the columns at `lg`.
- Tip: Platform limits (X-11): every evergreen browser already treats `target="_blank"` as `noopener`; the explicit `rel` covers older engines. `noreferrer` also withholds the Referer header, so a destination's analytics will not attribute the visit to your site. Native `type="email"` validation wording and strictness vary by browser — validate on the server as well.
Accessibility
- Rendered as a labelled contentinfo footer landmark with nav landmarks for links and legal.
- The newsletter field has an associated (visually-hidden) label and native email validation.
- Newsletter status is announced through a polite live region that is always present (a region inserted with its text is not reliably announced). On `error` the field is `aria-invalid` and described by the message.
- Focus while pending (X-10): the field goes read-only and the button `aria-disabled` rather than `disabled`, so the keyboard focus the user submitted from stays where it is; a second submit is ignored.
- Each footer, and its heading and email field, gets a per-instance id, so two footers on one page no longer point their `aria-labelledby` at the first one's heading. The two `<nav>`s carry distinct names (`navLabel` / `legalNavLabel`); a dev-mode warning fires if they match.
- Social and payment glyphs are decorative (aria-hidden) with accessible labels / titles on their controls; visible focus states in light and dark mode.
Feedback on Site Footer
Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.