Store Footer
Storefront footers — newsletter signup, multi-column link lists, social icons, locale/currency selector and payment-method chips.
Preview
@props([
'brand' => 'Lumière',
'brandBlurb' => 'Thoughtfully designed pieces for everyday living.',
'newsletterHeading' => 'Get 10% off your first order',
'newsletterSubcopy' => 'Subscribe to receive style tips, new arrivals, and exclusive offers.',
'columns' => [
[
'heading' => 'Shop',
'links' => [
['label' => 'Women', 'href' => '#'],
['label' => 'Men', 'href' => '#'],
['label' => 'Kids', 'href' => '#'],
['label' => 'Home', 'href' => '#'],
['label' => 'Sale', 'href' => '#'],
],
],
[
'heading' => 'Customer Service',
'links' => [
['label' => 'Help Centre', 'href' => '#'],
['label' => 'Returns & Exchanges','href' => '#'],
['label' => 'Order Tracking', 'href' => '#'],
['label' => 'Size Guide', 'href' => '#'],
],
],
[
'heading' => 'Company',
'links' => [
['label' => 'About Us', 'href' => '#'],
['label' => 'Careers', 'href' => '#'],
['label' => 'Press', 'href' => '#'],
['label' => 'Sustainability','href' => '#'],
],
],
[
'heading' => 'Legal',
'links' => [
['label' => 'Privacy Policy', 'href' => '#'],
['label' => 'Terms of Service','href' => '#'],
['label' => 'Cookie Policy', 'href' => '#'],
['label' => 'Accessibility', 'href' => '#'],
],
],
],
'socials' => [
['label' => 'Instagram', 'href' => '#'],
['label' => 'Pinterest', 'href' => '#'],
['label' => 'X', 'href' => '#'],
],
'paymentMethods' => ['Visa', 'Mastercard', 'Amex', 'PayPal', 'Apple Pay'],
'copyright' => '© 2025 Lumière. All rights reserved.',
])
{{--
store-footer — Commerce mega-footer with newsletter + payment badges.
Top: newsletter row.
Middle: brand column + 4 link-grid columns.
Bottom bar: copyright, locale select, payment-method chips.
Composes <x-ui.input>, <x-ui.button> and <x-ui.social-links>.
Semantic tokens only, logical spacing, RTL-safe, WCAG AA.
--}}
@php
// Map the block's `socials` contract onto social-links: `platform` (or the older
// `icon` key / a label) picks the mark; a raw `path` becomes a custom `icon`.
$socialLinks = array_map(fn (array $s) => [
'platform' => $s['platform'] ?? (isset($s['icon']) && ! str_contains($s['icon'], '<') ? $s['icon'] : strtolower(str_replace('.', '', $s['label'] ?? 'x'))),
'label' => $s['label'] ?? null,
'href' => $s['href'] ?? '#',
'icon' => isset($s['path']) ? '<path d="'.$s['path'].'"/>' : (isset($s['icon']) && str_contains($s['icon'], '<') ? $s['icon'] : null),
], $socials);
@endphp
<x-ui.section space="none" {{ $attributes }}>
<footer>
{{-- ── Newsletter band ── --}}
<div class="border-b border-border bg-card">
<div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div class="flex flex-col gap-6 md:flex-row md:items-center md:justify-between">
<div class="max-w-sm">
<h2 class="text-xl font-semibold text-foreground">{{ __($newsletterHeading) }}</h2>
<p class="mt-2 text-sm text-muted-foreground">{{ __($newsletterSubcopy) }}</p>
</div>
<form
class="flex w-full max-w-md flex-col gap-2 sm:flex-row"
method="POST"
action="#"
novalidate
>
@csrf
<label for="footer-email" class="sr-only">{{ __('Email address') }}</label>
<x-ui.input
id="footer-email"
type="email"
name="email"
:placeholder="__('your@email.com')"
autocomplete="email"
required
class="min-w-0 flex-1"
/>
<x-ui.button type="submit">
{{ __('Subscribe') }}
</x-ui.button>
</form>
</div>
</div>
</div>
{{-- ── Link grid ── --}}
<div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 gap-8 sm:grid-cols-3 lg:grid-cols-5">
{{-- Brand column --}}
<div class="col-span-2 sm:col-span-3 lg:col-span-1">
<a href="#" class="text-xl font-bold tracking-tight text-foreground">
{{ $brand }}
</a>
<p class="mt-4 max-w-xs text-sm leading-relaxed text-muted-foreground">
{{ __($brandBlurb) }}
</p>
{{-- Social icon buttons --}}
<x-ui.social-links :links="$socialLinks" variant="outline" size="sm" class="mt-4" />
</div>
{{-- Link columns --}}
@foreach ($columns as $column)
<div>
<h3 class="mb-4 text-sm font-semibold text-foreground">{{ __($column['heading']) }}</h3>
<ul class="space-y-4" role="list">
@foreach ($column['links'] as $link)
<li>
<a
href="{{ $link['href'] }}"
class="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
{{ __($link['label']) }}
</a>
</li>
@endforeach
</ul>
</div>
@endforeach
</div>
</div>
{{-- ── Bottom bar ── --}}
<div class="border-t border-border">
<div class="mx-auto flex max-w-7xl flex-col items-center gap-4 px-4 py-6 sm:px-6 sm:flex-row sm:justify-between lg:px-8">
{{-- Copyright --}}
<p class="text-sm text-muted-foreground">{{ __($copyright) }}</p>
{{-- Locale select --}}
<div class="flex items-center gap-2">
<label for="footer-locale" class="sr-only">{{ __('Language and currency') }}</label>
<x-ui.select size="sm" id="footer-locale" name="locale" class="w-max" aria-label="{{ __('Language and currency') }}">
<option value="en-usd">{{ __('English / USD') }}</option>
<option value="en-gbp">{{ __('English / GBP') }}</option>
<option value="fr-eur">{{ __('Français / EUR') }}</option>
</x-ui.select>
</div>
{{-- Payment method chips --}}
<div class="flex flex-wrap items-center gap-2" aria-label="{{ __('Accepted payment methods') }}" role="list">
@foreach ($paymentMethods as $method)
<x-ui.badge variant="outline" size="sm" role="listitem" class="text-muted-foreground">{{ $method }}</x-ui.badge>
@endforeach
</div>
</div>
</div>
</footer>
</x-ui.section>
Installation
php artisan ui:add blocks/store-footer
Registry contract
Install confidence
php artisan ui:add blocks/store-footer
writes only the generated targets below. The CLI validates each file hash before writing and
prompts before replacing local changes unless --force is used.
- Version
- 1.2.2
- License
- open
- Stability
- stable
- Contract
- v1
- Foundation
- ≥ 1.0.0
| Type | Generated target |
|---|---|
| blade | resources/views/blocks/store-footer.blade.php |
Registry dependencies
Package dependencies
composer: jml/brok:^0.2
Use with AI
A brief for your coding agent: what the block is, the install command, how to render it, its props and the rules. Copy it, or open a prompt about this block in an assistant.
# Brok UI block: Store Footer (`store-footer`)
Commerce mega-footer with a newsletter subscription row, responsive multi-column link grid, brand column with social icons, and a bottom bar with locale selector and payment-method chips.
Brok UI is a Laravel Blade registry. `ui:add` copies this block into the app as plain Blade the app owns; it composes installed `<brok:*>` primitives and semantic design tokens.
## Install
```bash
php artisan ui:add blocks/store-footer
```
## Render it
```blade
<x-blocks.store-footer />
```
## Props
- `brand` (string, default `Lumière`) — Brand name shown in the brand column.
- `brand-blurb` (string, default `Thoughtfully designed pieces for everyday living.`) — Short brand description under the name.
- `newsletter-heading` (string, default `Get 10% off your first order`) — Newsletter row heading.
- `newsletter-subcopy` (string, default `Subscribe to receive style tips, new arrivals, and exclusive offers.`) — Newsletter row supporting copy.
- `columns` (array, default `[…]`) — Link columns, each with a heading and a list of links.
- `socials` (array, default `[…]`) — Social icon links shown in the brand column; null falls back to sample data.
- `payment-methods` (array, default `['Visa', 'Mastercard', 'Amex', 'PayPal', 'Apple Pay']`) — Payment-method chips shown in the bottom bar; null falls back to sample data.
- `copyright` (string, default `© 2025 Lumière. All rights reserved.`) — Copyright line shown in the bottom bar; null falls back to a generated year and brand line.
## Use when
- Building a commerce mega-footer with a newsletter subscription row, a multi-column link grid and payment-method chips.
- Wanting a full-featured footer for a storefront rather than a minimal one.
## Avoid when
- Wanting a quieter, editorial-styled footer; use store-footer-minimal instead.
## Rules
- Render the installed block with `<x-blocks.store-footer />` and pass data through its props; edit the copied file only for structural changes.
- Keep the semantic design tokens (`bg-background`, `text-muted-foreground`); never swap in raw colour utilities.
- Keep the `data-slot` attributes and the logical (start/end) spacing so the markup still mirrors under `dir="rtl"`.
## Links
- Docs: https://brokui.dev/blocks/store-footer
- Registry JSON (files, props, contract): https://brokui.dev/r/open/blocks/store-footer.json
Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.
Guidance
Use when
- Building a commerce mega-footer with a newsletter subscription row, a multi-column link grid and payment-method chips.
- Wanting a full-featured footer for a storefront rather than a minimal one.
Avoid when
- Wanting a quieter, editorial-styled footer; use store-footer-minimal instead.
Anti-patterns
- Do not replace semantic props with conflicting utility classes.
- Do not remove labels, focus styles, or state attributes.
Usage
Render the block as a component, passing data where useful:
<x-blocks.store-footer />
Built from primitives
This block composes installed <brok:*> primitives and semantic design
tokens only — it does not reimplement any primitive. Re-theme it (light, dark, admin, customer) by
editing CSS variables; flip the preview to RTL to confirm it mirrors.
Source
The exact, editable file ui:add writes
into your app. The preview above renders this same source — there are no preview-only blocks.
@props([
'brand' => 'Lumière',
'brandBlurb' => 'Thoughtfully designed pieces for everyday living.',
'newsletterHeading' => 'Get 10% off your first order',
'newsletterSubcopy' => 'Subscribe to receive style tips, new arrivals, and exclusive offers.',
'columns' => [
[
'heading' => 'Shop',
'links' => [
['label' => 'Women', 'href' => '#'],
['label' => 'Men', 'href' => '#'],
['label' => 'Kids', 'href' => '#'],
['label' => 'Home', 'href' => '#'],
['label' => 'Sale', 'href' => '#'],
],
],
[
'heading' => 'Customer Service',
'links' => [
['label' => 'Help Centre', 'href' => '#'],
['label' => 'Returns & Exchanges','href' => '#'],
['label' => 'Order Tracking', 'href' => '#'],
['label' => 'Size Guide', 'href' => '#'],
],
],
[
'heading' => 'Company',
'links' => [
['label' => 'About Us', 'href' => '#'],
['label' => 'Careers', 'href' => '#'],
['label' => 'Press', 'href' => '#'],
['label' => 'Sustainability','href' => '#'],
],
],
[
'heading' => 'Legal',
'links' => [
['label' => 'Privacy Policy', 'href' => '#'],
['label' => 'Terms of Service','href' => '#'],
['label' => 'Cookie Policy', 'href' => '#'],
['label' => 'Accessibility', 'href' => '#'],
],
],
],
'socials' => [
['label' => 'Instagram', 'href' => '#'],
['label' => 'Pinterest', 'href' => '#'],
['label' => 'X', 'href' => '#'],
],
'paymentMethods' => ['Visa', 'Mastercard', 'Amex', 'PayPal', 'Apple Pay'],
'copyright' => '© 2025 Lumière. All rights reserved.',
])
{{--
store-footer — Commerce mega-footer with newsletter + payment badges.
Top: newsletter row.
Middle: brand column + 4 link-grid columns.
Bottom bar: copyright, locale select, payment-method chips.
Composes <x-ui.input>, <x-ui.button> and <x-ui.social-links>.
Semantic tokens only, logical spacing, RTL-safe, WCAG AA.
--}}
@php
// Map the block's `socials` contract onto social-links: `platform` (or the older
// `icon` key / a label) picks the mark; a raw `path` becomes a custom `icon`.
$socialLinks = array_map(fn (array $s) => [
'platform' => $s['platform'] ?? (isset($s['icon']) && ! str_contains($s['icon'], '<') ? $s['icon'] : strtolower(str_replace('.', '', $s['label'] ?? 'x'))),
'label' => $s['label'] ?? null,
'href' => $s['href'] ?? '#',
'icon' => isset($s['path']) ? '<path d="'.$s['path'].'"/>' : (isset($s['icon']) && str_contains($s['icon'], '<') ? $s['icon'] : null),
], $socials);
@endphp
<x-ui.section space="none" {{ $attributes }}>
<footer>
{{-- ── Newsletter band ── --}}
<div class="border-b border-border bg-card">
<div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div class="flex flex-col gap-6 md:flex-row md:items-center md:justify-between">
<div class="max-w-sm">
<h2 class="text-xl font-semibold text-foreground">{{ __($newsletterHeading) }}</h2>
<p class="mt-2 text-sm text-muted-foreground">{{ __($newsletterSubcopy) }}</p>
</div>
<form
class="flex w-full max-w-md flex-col gap-2 sm:flex-row"
method="POST"
action="#"
novalidate
>
@csrf
<label for="footer-email" class="sr-only">{{ __('Email address') }}</label>
<x-ui.input
id="footer-email"
type="email"
name="email"
:placeholder="__('your@email.com')"
autocomplete="email"
required
class="min-w-0 flex-1"
/>
<x-ui.button type="submit">
{{ __('Subscribe') }}
</x-ui.button>
</form>
</div>
</div>
</div>
{{-- ── Link grid ── --}}
<div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 gap-8 sm:grid-cols-3 lg:grid-cols-5">
{{-- Brand column --}}
<div class="col-span-2 sm:col-span-3 lg:col-span-1">
<a href="#" class="text-xl font-bold tracking-tight text-foreground">
{{ $brand }}
</a>
<p class="mt-4 max-w-xs text-sm leading-relaxed text-muted-foreground">
{{ __($brandBlurb) }}
</p>
{{-- Social icon buttons --}}
<x-ui.social-links :links="$socialLinks" variant="outline" size="sm" class="mt-4" />
</div>
{{-- Link columns --}}
@foreach ($columns as $column)
<div>
<h3 class="mb-4 text-sm font-semibold text-foreground">{{ __($column['heading']) }}</h3>
<ul class="space-y-4" role="list">
@foreach ($column['links'] as $link)
<li>
<a
href="{{ $link['href'] }}"
class="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
{{ __($link['label']) }}
</a>
</li>
@endforeach
</ul>
</div>
@endforeach
</div>
</div>
{{-- ── Bottom bar ── --}}
<div class="border-t border-border">
<div class="mx-auto flex max-w-7xl flex-col items-center gap-4 px-4 py-6 sm:px-6 sm:flex-row sm:justify-between lg:px-8">
{{-- Copyright --}}
<p class="text-sm text-muted-foreground">{{ __($copyright) }}</p>
{{-- Locale select --}}
<div class="flex items-center gap-2">
<label for="footer-locale" class="sr-only">{{ __('Language and currency') }}</label>
<x-ui.select size="sm" id="footer-locale" name="locale" class="w-max" aria-label="{{ __('Language and currency') }}">
<option value="en-usd">{{ __('English / USD') }}</option>
<option value="en-gbp">{{ __('English / GBP') }}</option>
<option value="fr-eur">{{ __('Français / EUR') }}</option>
</x-ui.select>
</div>
{{-- Payment method chips --}}
<div class="flex flex-wrap items-center gap-2" aria-label="{{ __('Accepted payment methods') }}" role="list">
@foreach ($paymentMethods as $method)
<x-ui.badge variant="outline" size="sm" role="listitem" class="text-muted-foreground">{{ $method }}</x-ui.badge>
@endforeach
</div>
</div>
</div>
</footer>
</x-ui.section>
Ownership & lifecycle
Owner, release state, review evidence and adoption for this item.
- Owner
- Platform UI (@JoshJML)
- Current version
-
1.2.2 - Status
- Stable
- License
-
open - Deprecation
- Not deprecated
- Contract
-
v1 - Foundation
-
≥ 1.0.0