Footer — Multi-Column

Multi-column footer with navigation links, social icons, and copyright. Zero-JS Astro component.

Navigation

Installation

npx shadcn@latest add @saastro/footer-01

Preview

Footer — Multi-Column preview

Source Code

---
/**
 * footer-01 — Footer multicolumna con enlaces, sociales y copyright.
 * Bloque Astro puro: cero JS, cero dependencias.
 *
 * `logo` es un string (el nombre de la marca); `socialLinks[].icon` es una
 * clave del set interno ('github' | 'x' | 'linkedin') — props serializables.
 */
type SocialIcon = 'github' | 'x' | 'linkedin';

interface LinkItem {
  label: string;
  href: string;
}
interface Column {
  title: string;
  links: LinkItem[];
}
interface SocialLink {
  icon: SocialIcon;
  href: string;
  label: string;
}
interface Props {
  logo?: string;
  columns: Column[];
  copyright?: string;
  socialLinks?: SocialLink[];
  class?: string;
}
const {
  logo,
  columns,
  copyright = `© ${new Date().getFullYear()} All rights reserved.`,
  socialLinks,
  class: className,
} = Astro.props;

const SOCIAL: Record<SocialIcon, string> = {
  github:
    '<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65S8.93 17.38 9 18v4"/><path d="M9 18c-4.51 2-5-2-7-2"/>',
  x: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
  linkedin:
    '<path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"/><rect width="4" height="12" x="2" y="9"/><circle cx="4" cy="4" r="2"/>',
};
---

<footer class:list={['w-full px-6 py-16', className]}>
  <div class="mx-auto max-w-6xl">
    <div class="grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
      {logo && (
        <div class="sm:col-span-2 lg:col-span-1">
          <span class="text-xl font-bold">{logo}</span>
        </div>
      )}
      {columns.map((column) => (
        <div>
          <h3 class="mb-4 text-sm font-semibold">{column.title}</h3>
          <ul class="space-y-3">
            {column.links.map((link) => (
              <li>
                <a
                  href={link.href}
                  class="text-sm text-muted-foreground transition-colors hover:text-foreground"
                >
                  {link.label}
                </a>
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
    <hr class="my-8 h-px w-full shrink-0 border-0 bg-border" />
    <div class="flex flex-col items-center justify-between gap-4 sm:flex-row">
      <p class="text-sm text-muted-foreground">{copyright}</p>
      {socialLinks && socialLinks.length > 0 && (
        <div class="flex items-center gap-4">
          {socialLinks.map((social) => (
            <a
              href={social.href}
              aria-label={social.label}
              class="text-muted-foreground transition-colors hover:text-foreground"
            >
              <svg
                xmlns="http://www.w3.org/2000/svg"
                width="18"
                height="18"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
                set:html={SOCIAL[social.icon]}
              />
            </a>
          ))}
        </div>
      )}
    </div>
  </div>
</footer>

Registry Setup

Add the Saastro registry to your components.json:

{
  "registries": {
    "@saastro": "https://ui.saastro.io/r/{name}.json"
  }
}