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-01Preview

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"
}
}