hexui
blockfooter-1source: ok · hit
Footer-1
A simple, professional footer that includes a subscription form
npx shadcn add "https://hexui.sh/r/footer-1.json"free
Where it goes
footer
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lighticonslucide-react
Registry dependencies
buttoninput
Files4 · source cached 10/15/2026, 6:15:31 AM
registry/blocks/footer/footer-1/source/app/footer/page.tsx
import { SiteFooter } from "../../components/site-footer"
export default function Page() {
return (
<div className="flex w-full min-h-dvh items-center justify-center">
<SiteFooter />
</div>
)
}
registry/blocks/footer/footer-1/source/components/site-footer.tsx
import Link from "next/link"
import { Command } from "lucide-react"
import { SubscribeForm } from "./subscribe-form"
import { NavLinks } from "./nav-links"
const footerSections = [
{
title: "Product",
links: [
{ label: "Features", href: "#" },
{ label: "Pricing", href: "#" },
{ label: "Case Studies", href: "#" },
{ label: "Changelog", href: "#" },
],
},
{
title: "Company",
links: [
{ label: "About Us", href: "#" },
{ label: "Careers", href: "#" },
{ label: "Blog", href: "#" },
{ label: "Contact", href: "#" },
],
},
{
title: "Resources",
links: [
{ label: "Documentation", href: "#" },
{ label: "API Reference", href: "#" },
{ label: "Guides", href: "#" },
{ label: "Support", href: "#" },
],
},
{
title: "Legal",
links: [
{ label: "Terms of Service", href: "#" },
{ label: "Privacy Policy", href: "#" },
{ label: "Cookie Settings", href: "#" },
],
},
]
export function SiteFooter() {
return (
<footer className="w-full border-t border-border">
<div className="mx-auto max-w-7xl px-6 py-12 md:px-8 md:pb-16 md:pt-12">
<div className="flex flex-col gap-8 sm:gap-12 xl:flex-row">
{/* Brand + newsletter column takes 1/3 on xl; the nav links take the remaining 2/3. */}
<div className="space-y-6 xl:w-1/3 xl:max-w-sm">
<Link
href="#"
className="flex items-center gap-2 rounded outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
>
<Command />
<span className="text-xl font-semibold text-foreground">
Acme Inc.
</span>
</Link>
<p className="max-w-xs text-sm leading-relaxed text-muted-foreground">
Streamline workflows, ship faster, and stay ahead with AI.
</p>
<div className="flex flex-col gap-2 text-sm text-muted-foreground">
<p>Subscribe to our newsletter:</p>
<SubscribeForm />
</div>
</div>
<NavLinks sections={footerSections} />
</div>
<div className="mt-8 flex flex-col items-center gap-4 border-t border-border pt-8 md:flex-row md:justify-between">
<p className="text-xs text-muted-foreground">
© {new Date().getFullYear()} Acme Inc. All rights reserved.
</p>
<div className="flex gap-6">
<Link
href="#"
className="rounded text-xs text-muted-foreground transition-colors hover:text-foreground outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
>
Sitemap
</Link>
<Link
href="#"
className="rounded text-xs text-muted-foreground transition-colors hover:text-foreground outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
>
Cookie
</Link>
</div>
</div>
</div>
</footer>
)
}
registry/blocks/footer/footer-1/source/components/nav-links.tsx
import Link from "next/link"
type FooterLinkItem = {
label: string
href: string
}
type FooterSection = {
title: string
links: FooterLinkItem[]
}
type NavLinksProps = {
sections: FooterSection[]
}
export function NavLinks({ sections }: NavLinksProps) {
return (
<div className="grid grid-cols-2 gap-6 sm:gap-8 xl:w-2/3 xl:flex-1 xl:grid-cols-4">
{sections.map((section) => (
<div key={section.title}>
<h3 className="text-sm font-semibold text-foreground">{section.title}</h3>
{/* role="list" keeps list semantics; Tailwind preflight strips default list styles. */}
<ul role="list" className="mt-4 space-y-2 sm:space-y-3">
{section.links.map((item) => (
<li key={item.label}>
<Link
href={item.href}
className="rounded text-sm text-muted-foreground transition-colors hover:text-foreground outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
>
{item.label}
</Link>
</li>
))}
</ul>
</div>
))}
</div>
)
}
registry/blocks/footer/footer-1/source/components/subscribe-form.tsx
import { ArrowRight } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
export function SubscribeForm() {
return (
<form className="flex items-center gap-2">
<label htmlFor="email-address" className="sr-only">
Email address
</label>
<Input
type="email"
id="email-address"
name="email"
autoComplete="email"
spellCheck={false}
placeholder="your email…"
/>
<Button type="submit" size="icon" variant="outline" aria-label="Subscribe">
<ArrowRight />
</Button>
</form>
)
}