Minimal footer

One compact row: mark, inline links, social icons, and copyright.

blockminimalany
$npx shadcn@latest add @storekit/footer-minimal
footer-minimal

Live and interactive. Switch the brand in the frame header to see the same source under another token file.

Installation

$npx shadcn@latest add @storekit/footer-minimal
$pnpm dlx shadcn@latest add @storekit/footer-minimal
$yarn dlx shadcn@latest add @storekit/footer-minimal
$bunx --bun shadcn@latest add @storekit/footer-minimal

Source

components/storekit/footer/footer-minimal.tsx
73 lines
import { Instagram, Twitter, Youtube } from "lucide-react"
import { cn } from "@/components/storekit/lib/cn"

/* One-row footer: mark and name, inline links, social icons, copyright.
   On small screens: mark and socials, then links, then copyright. No client
   state. */

const ring =
  "outline-none focus-visible:ring-2 focus-visible:ring-sk-accent focus-visible:ring-offset-2 focus-visible:ring-offset-sk-paper"

export function FooterMinimal({
  brandName = "Morrow",
  markSrc,
  links = [
    { label: "Shop", href: "#shop" },
    { label: "Lab results", href: "#lab-results" },
    { label: "Shipping", href: "#shipping" },
    { label: "Privacy", href: "#privacy" },
  ],
  social = { instagram: "https://instagram.com", x: "https://x.com", youtube: "https://youtube.com" },
  className,
}: {
  brandName?: string
  markSrc?: string
  links?: { label: string; href: string }[]
  social?: { instagram?: string; x?: string; youtube?: string }
  className?: string
}) {
  const icons = [
    { href: social.instagram, label: "Instagram", Icon: Instagram },
    { href: social.x, label: "X", Icon: Twitter },
    { href: social.youtube, label: "YouTube", Icon: Youtube },
  ].filter((s) => s.href)

  return (
    <footer data-sk-section="footer" data-sk-variant="footer-minimal" className={cn("border-t border-sk-line bg-sk-paper text-sk-ink", className)}>
      <div className="mx-auto flex max-w-6xl flex-wrap items-center gap-x-6 px-4 py-4 sm:px-8">
        <a href="/" className={cn("flex min-h-11 items-center gap-2 rounded-sk-btn pr-1", ring)}>
          {markSrc ? <img src={markSrc} alt="" className="h-6 w-6 object-contain" /> : null}
          <span className="font-sk-display text-sm font-semibold tracking-[-0.02em]">{brandName}</span>
        </a>
        <nav aria-label="Footer" className="order-3 w-full md:order-none md:w-auto md:flex-1">
          <ul className="flex flex-wrap items-center gap-x-4">
            {links.map((l) => (
              <li key={l.href}>
                <a href={l.href} className={cn("inline-flex min-h-11 items-center rounded-sk-btn text-[13px] text-sk-muted transition-colors duration-200 hover:text-sk-ink", ring)}>
                  {l.label}
                </a>
              </li>
            ))}
          </ul>
        </nav>
        <ul className="-mr-3 ml-auto flex items-center md:mr-0 md:ml-0">
          {icons.map(({ href, label, Icon }) => (
            <li key={label}>
              <a
                href={href}
                aria-label={label}
                target="_blank"
                rel="noreferrer"
                className={cn("grid h-11 w-11 place-items-center rounded-sk-btn text-sk-muted transition-colors duration-200 hover:text-sk-ink", ring)}
              >
                <Icon size={16} aria-hidden />
              </a>
            </li>
          ))}
        </ul>
        <p className="order-4 w-full pt-1 text-[13px] text-sk-muted md:order-none md:w-auto md:pt-0">&copy; {new Date().getFullYear()} {brandName}</p>
      </div>
    </footer>
  )
}

Usage

Import from "@/components/storekit/footer/footer-minimal" and pass your product data. The demo above exercises the full prop surface with sample values.

Minimal footer, StoreKit