A single event page opening on a full-bleed photo band with a live countdown anchored into it, then pairing the pitch and two actions with a hairline table of practical facts and a speaker list.
A single event page opening on a full-bleed photo band with a live countdown anchored into it, then pairing the pitch and two actions with a hairline table of practical facts and a speaker list.
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/event96?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/event96?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/event96.tsx, the event12 countdown piece it anchors into the band (installed to components/beste/piece/event12.tsx), and the badge23 and button21 components it uses for the eyebrow and the actions.
The installed file exports event96Demo alongside the block: the exact props behind the preview above. Spread it to get a working event page in one line.
import { Event96, event96Demo } from "@/components/beste/block/event96";
export default function EventPage() {
return <Event96 {...event96Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Event12 } from "@/components/beste/piece/event12";
import { Event96 } from "@/components/beste/block/event96";
export default function EventPage() {
return (
<Event96
badge={{ label: "Practice Day 2026" }}
heading="One day in Bristol with the people who run clinics"
description="Forty seats, three tracks, and no exhibition hall."
image={{ src: "/events/practice-day.jpg", alt: "A bright event space" }}
media={
<Event12
title="Doors open in"
units={[
{ value: "12", label: "days" },
{ value: "06", label: "hrs" },
]}
caption="Registration closes when the last seat goes."
/>
}
facts={[
{ label: "Date", value: "Thursday 18 June 2026" },
{ label: "Venue", value: "The Old Print Works, Bristol" },
{ label: "Cost", value: "Free, lunch included" },
]}
buttons={[
{ label: "Reserve a seat", href: "/register" },
{ label: "See the full agenda", href: "/agenda" },
]}
speakersTitle="Who is speaking"
speakers={[
{
name: "Elena Rourke",
role: "Practice lead, Bramble Health",
topic: "The morning huddle, rebuilt",
avatar: { src: "/people/elena.jpg", alt: "Portrait of Elena Rourke" },
},
]}
note="If cost or travel is the thing stopping you, write to us."
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow above the heading, below the band |
heading | string | – | Event heading |
description | string | – | Supporting paragraph, capped at max-w-xl |
image | { src: string; alt: string } | – | Full-bleed band opening the page |
media | ReactNode | – | Countdown anchored into the band, event12 in the demo |
facts | Fact[] | [] | Practical details in a hairline table |
buttons | ActionLink[] | [] | Actions, first solid and the rest outlined |
speakersTitle | string | – | Heading above the speaker list |
speakers | Speaker[] | [] | Speakers with their portrait and topic |
note | string | – | Accessibility or cost note under the actions |
className | string | – | Extra classes for the outer section |
type ActionLink = {
label: string;
href: string;
};
type BandImage = {
src: string;
alt: string;
};
type Fact = {
label: string;
value: string;
};
type Speaker = {
name: string;
role: string;
topic: string;
avatar: { src: string; alt: string };
};event12 receives strings, and the block runs no timer, so the page stays safe to server-render with no hydration mismatch. Wiring a live counter means adding state around the piece.section, outside the max-w-7xl wrapper, so it runs edge to edge. The section carries pt-16 only, and the bottom padding lives on the content wrapper.inset-y-0 right-0, moving to md:right-12, and width-capped at w-80. It is vertically centered inside the band rather than offset, so band height changes do not push it out of frame.dl using flex-wrap items-baseline, so a long value wraps below its label rather than crushing it.border-t with no closing rule, so the table stays open at the bottom.sm, filling column by column, and use min-w-0 so a long role wraps under the name instead of pushing the portrait.topic is required on every speaker. A speaker list that names people without saying what they will talk about is the thing this block is built against.event94
An events section that opens with a split featured card pairing a photo with date, time, and format lines, then lists the rest of the schedule as rows separated by hairlines, each with a bordered date tile, host meta, seat count, and register action.
event4
Split-layout event hero displaying conference details with date, location, attendee count, and featured image. Perfect for developer conferences and tech summits.
event17
Host profiles with photos, bios, and social media links displayed in a two-column grid. Perfect for introducing conference MCs and event directors.
event95
A conference agenda whose track pills are derived from the sessions and carry live counts, narrowing a timed list of hairline rows that align the slot, the session, and its speaker and room.