Hartwell & Lowe, riverside homes
New and recent homes from Mill Lane to Granary Square, sold by the people who built them. Search by place, type and budget, or start from one of the collections below.

A search hero for an estate agency page: eyebrow, large sans headline and intro, then a search bar under a hairline with a location field, three selects (property type, bedrooms, maximum price) and a submit pill, posted as a GET request to a listings URL with configurable parameter names; three quick-link pills under it and a wide 21:9 photograph below that is unveiled once loaded and drifts against the scroll.
A search hero for an estate agency page: a rule eyebrow, a large sans headline and an intro in the header grid, then a search bar under a hairline with a location field, three selects (property type, bedrooms, maximum price) and a submit pill, submitted as a GET request to a listings URL with configurable parameter names. Three quick-link pills sit under the bar, and a wide 21:9 photograph of the river walk below is unveiled once loaded and drifts slowly against the scroll.
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/realestate16?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/realestate16?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/realestate16.tsx plus the badge24 rule eyebrow, the button25 pill behind the submit button, and the shadcn/ui button, input and select primitives behind the controls.
The installed file exports realestate16Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Realestate16, realestate16Demo } from "@/components/beste/block/realestate16";
export default function Page() {
return <Realestate16 {...realestate16Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Realestate16 } from "@/components/beste/block/realestate16";
export default function Page() {
return (
<Realestate16
eyebrow="Hartwell & Lowe, riverside homes"
heading="Find a home along the river."
description="New and recent homes from Mill Lane to Granary Square, sold by the people who built them."
form={{
action: "/homes",
params: { location: "q", type: "type", bedrooms: "beds", maxPrice: "max_price" },
types: [
{ label: "Apartment", value: "apartment" },
{ label: "Penthouse", value: "penthouse" },
],
bedrooms: [
{ label: "2 bedrooms", value: "2" },
{ label: "3 bedrooms", value: "3" },
],
prices: [
{ label: "$750,000", value: "750000" },
{ label: "No limit", value: "0" },
],
}}
quickLinks={[
{ label: "Alder Row, launching now", href: "/alder-row" },
{ label: "Ready to move in", href: "/homes?status=ready" },
]}
image={{
src: "https://oud.pics/b/realestate/alder-river-walk.webp",
alt: "The stone river promenade beside the warehouse and the concrete wing",
}}
labels={{
location: "Where",
locationPlaceholder: "Area, street or station",
type: "Property type",
typePlaceholder: "Any type",
bedrooms: "Bedrooms",
bedroomsPlaceholder: "Any",
maxPrice: "Maximum price",
maxPricePlaceholder: "No limit",
submit: "Search homes",
quickLinks: "Or browse",
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Short line above the headline, rendered through badge24 on mount. |
heading | string | – | The headline, rendered as an h1. |
description | string | – | Intro paragraph in the right column of the header grid. |
form | SearchForm | – | The GET form: its action, the parameter names and the options of the three selects. |
quickLinks | QuickLink[] | [] | Outline pills under the search bar linking to collections. |
image | { src: string; alt: string } | – | The wide photograph under the search bar. |
labels | Labels | {} | Field labels, placeholders, the submit label and the quick links caption. |
className | string | – | Extra classes merged onto the section. |
type Option = { label: string; value: string };
type SearchForm = {
action: string;
params?: { location?: string; type?: string; bedrooms?: string; maxPrice?: string };
types?: Option[];
bedrooms?: Option[];
prices?: Option[];
};
type QuickLink = { label: string; href: string };
type Labels = {
location?: string;
locationPlaceholder?: string;
type?: string;
typePlaceholder?: string;
bedrooms?: string;
bedroomsPlaceholder?: string;
maxPrice?: string;
maxPricePlaceholder?: string;
submit?: string;
quickLinks?: string;
};form with method="get". The location Input and the three Selects carry the names from form.params (falling back to q, type, beds and max_price), so a submit produces a URL like /homes?q=riverside&type=apartment&beds=2&max_price=750000 with no script; a select left on its placeholder sends nothing.h-11 rounded-full treatment, the submit is a button25 with a search icon and stretches to full width below md.Links styled as outline pills; the caption before them is optional.load event (or the cached complete flag), opens from the top over 1.6 seconds while the image settles from a 1.18 to a 1.12 scale, and drifts from -6% to 6% as the frame crosses the viewport.prefers-reduced-motion every entrance, the clip reveal and the parallax are disabled and the hero renders in its final state.Wiring the form up
The form submits as a GET request to the action you pass, with the field names from params. To validate on the client and handle submission in React instead, see React Hook Form, TanStack Form, and Formisch.