A centred photographic hero built around a search field: the photograph blurs in and drifts slower than the page under a dark scrim and film grain, a serif headline settles in word by word, then a rounded search field with a keyboard shortcut hint, a row of quick links and optional pills. The field can hand its click to a command palette instead of being a form.
A photographic hero built around a search field: the picture clears from a blur and drifts under a dark scrim and film grain, the headline settles in word by word, and a rounded field with a keyboard hint sits under it above a row of quick links.
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://ui.beste.co/r/hero187?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/hero187?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hero187.tsx, the shadcn input primitive the field is built on, and the button22 sliding-marker pill and the text1 word stagger it uses.
The installed file exports hero187Demo alongside the block: the exact props behind the preview above. Spread it to get a working search hero in one line.
import { Hero187, hero187Demo } from "@/components/beste/block/hero187";
export default function Page() {
return <Hero187 {...hero187Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hero187 } from "@/components/beste/block/hero187";
export default function Page() {
return (
<Hero187
eyebrow="A library of finished screens"
heading="Already built."
description="Every section a website needs, written once and kept calm."
image={{ src: "/photos/hills.jpg", alt: "Soft fog rolling over layered green hills" }}
search={{
placeholder: "Search blocks, pieces and components",
label: "Search",
shortcut: ["⌘", "K"],
}}
onSearch={() => console.log("open the command palette")}
suggestionsLabel="Often opened"
suggestions={[
{ label: "Heroes", href: "/blocks/hero" },
{ label: "Pricing", href: "/blocks/pricing" },
]}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small-caps line above the headline |
heading | string | – | Headline, rendered as the page h1 through Text1 |
description | string | – | Paragraph under the headline |
image | { src: string; alt: string } | – | Full-bleed background photograph |
search | Search | – | The field's placeholder, accessible name and keyboard hint |
onSearch | () => void | – | When given, the field becomes a button that calls this instead of a form |
suggestions | Suggestion[] | [] | Quick links under the field |
suggestionsLabel | string | – | Small-caps label before the quick links |
buttons | ActionButton[] | [] | Pill actions under the links; each defaults to the light tone |
className | string | – | Extra classes for the outer <section> |
type Search = {
placeholder: string;
label: string;
shortcut?: string[];
};
type Suggestion = {
label: string;
href: string;
};
type ActionButton = {
label: string;
href: string;
tone?: "primary" | "light" | "dark" | "outline";
};onSearch changes what the field actually is. Without it you get a real form with an input; with it you get a button wearing the same shape, which is the right markup when the search lives in a command palette or on another page and this is only the thing you press to reach it.sr-only and tied to the input through a useId, so the field is named for a screen reader without a visible label crowding the pill; in the button variant that name comes from aria-label instead.shortcut is a plain array of strings, so ["⌘", "K"] and ["Ctrl", "K"] both render as key caps. It is aria-hidden and hidden below sm, since a keyboard hint is noise on a phone and on a screen reader.bg-background inside a dark hero, so it is the one light object on the screen; the shadcn Input is stripped of its border, shadow and focus ring so the pill around it reads as the control.min-h-[40rem] rising to min-h-[46rem] rather than min-h-svh: a search hero wants to leave the first results or section visible under it rather than filling the viewport.trigger="mount", since a hero is above the fold, and everything under it is offset from 0.4 + heading.split(" ").length * 0.07 so the field, the links and the buttons arrive in that order.1.12 scale and blur(24px) on decode, with a complete check on mount because a cached image fires its load event before hydration, and drifts 26% as the page scrolls away.preventDefault() on submit, so nothing is searched until you wire it up or hand the click to onSearch.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.
hero182
A full-height photographic hero with everything centred: the photograph zooms out on load and drifts slower than the page under a dark scrim and film grain, beneath an eyebrow, a serif headline that settles in word by word, an intro and two sliding-marker pills.
hero171
A centered hero whose main action is a search field rather than a button, with the week's most looked-up terms as chips beneath it and the size of the archive stated at the bottom.
hero176
A centred hero: eyebrow, a serif headline settling in word by word, intro and two sliding-marker pills, then a wide photograph that unveils itself from a smaller inset frame and keeps drifting as the page scrolls, closed by a row of dotted facts.
hero46
Centered hero with prominent search input field and popular search suggestion pills below. Perfect for documentation sites, knowledge bases, and support centers.