A light footer for a property development: the wordmark and a tagline beside four link columns (residences, the place, buying, the developer) that rise in one after another, a ruled register row with a heading, a line, an email field and a pill submit button as a plain GET form, and a legal row with the copyright, policy links and two notices about the consumer code and computer-generated images.
A light footer for a property development's sales site: the text wordmark and a tagline on the left beside four link columns (Residences, The place, Buying and the developer) that rise in one after another, then a ruled register row with a heading, a line, an email field and a pill submit button as a plain GET form, and finally a legal row with the copyright, policy links and two notices covering the consumer code and the computer-generated images. Every row sits under a hairline that draws from the left as it enters the viewport.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://beste.dev/r/realestate76?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/realestate76?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/realestate76.tsx plus the Button25 pill used for the submit button and the shadcn/ui button and input primitives behind the pill and the email field.
The installed file exports realestate76Demo alongside the block: the exact props behind the preview above. Spread it to get a working footer in one line.
import { Realestate76, realestate76Demo } from "@/components/beste/block/realestate76";
export default function Page() {
return <Realestate76 {...realestate76Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Realestate76 } from "@/components/beste/block/realestate76";
export default function Page() {
return (
<Realestate76
brand="Alder Row"
tagline="Twenty-four homes between a restored brick warehouse and a birch courtyard, on the river."
groups={[
{
title: "Residences",
links: [
{ label: "Type A, two bedroom", href: "/residences/type-a" },
{ label: "Type C, three bedroom", href: "/residences/type-c" },
{ label: "Type E, penthouse", href: "/residences/type-e" },
],
},
{
title: "Buying",
links: [
{ label: "Availability", href: "/availability" },
{ label: "Book a viewing", href: "/viewing" },
],
},
]}
form={{
action: "/register",
heading: "Register for updates",
description: "Phase 2 pricing, viewing days and construction news, about once a month.",
params: { email: "email" },
placeholder: "Your email address",
button: "Register",
}}
copyright="2026 Hartwell & Lowe. All rights reserved."
legalLinks={[
{ label: "Privacy", href: "/privacy" },
{ label: "Terms", href: "/terms" },
]}
notices={[
"Prices are correct at the time of publication and may change without notice.",
"Images are computer-generated and indicative only.",
]}
labels={{ email: "Email address" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
brand | string | – | Text wordmark at the top left. |
tagline | string | – | Short paragraph under the wordmark. |
groups | LinkGroup[] | [] | Link columns to the right of the wordmark; four fit in one row on desktop, two per row on small screens. |
form | RegisterForm | – | The register row: the GET action, its heading and line, the email parameter name, placeholder and submit label. Without it the row is left out. |
copyright | string | – | Copyright line at the left of the legal row. |
legalLinks | FooterLink[] | [] | Policy links at the right of the legal row. |
notices | string[] | [] | Legal notices under the legal row, two per row on desktop. |
labels | { email?: string } | {} | Visually hidden label for the email field. |
className | string | – | Extra classes merged onto the footer. |
type FooterLink = { label: string; href: string };
type LinkGroup = { title: string; links: FooterLink[] };
type RegisterForm = {
action: string;
heading?: string;
description?: string;
params?: { email?: string };
placeholder?: string;
button?: string;
};form with method="get" posting to form.action; the email field is type="email" with native required, is named by form.params.email (falling back to email) and carries a visually hidden label from labels.email.motion.span rules that scale from the left over 1.2 seconds with the row they belong to.md breakpoint; the form stacks its field and button vertically below the sm breakpoint and puts them side by side above it.prefers-reduced-motion every entrance and hairline draw is skipped and the footer renders in its final state.Wiring the form up
This block ships the form markup only; state, validation, and submit are yours to add. Our guide wires the shadcn Field primitives to React Hook Form, TanStack Form, and Formisch on one field system.