Skip to content
Brok UI

Loading…

No results

Store Footer

Open source

Storefront footers — newsletter signup, multi-column link lists, social icons, locale/currency selector and payment-method chips.

Preview

1 of 2

resources/views/blocks/store-footer.blade.php Blade
@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

terminal
php artisan ui:add blocks/store-footer

Installs these dependencies automatically:

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

badge button input section select social-links

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.

store-footer.md
# 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:

resources/views/welcome.blade.php Blade
<x-blocks.store-footer />

Built from primitives

Composes <brok:*> Semantic tokens Re-themeable RTL-ready

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.

resources/views/blocks/store-footer.blade.php Blade
@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