Guest book
9.7out of 10
From 412 stays since the house reopened
“We came for four nights and changed our ferry twice. Nobody tried to sell us anything; they just remembered everything.”
A reviews section for a small hotel: a large serif score with how many stays it comes from and four hairline bars that fill to each rating, beside large serif guest notes that blur from one to the next on a timer, with a row of hairlines that fill as each note plays, arrow controls and a pause on hover.
A large serif score with four hairline rating bars that fill to their values sits beside big serif guest notes that blur from one to the next on a timer, with a row of progress hairlines and arrow controls below.
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/hotel43?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/hotel43?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hotel43.tsx plus the text1 word stagger it uses for the heading.
The installed file exports hotel43Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Hotel43, hotel43Demo } from "@/components/beste/block/hotel43";
export default function Page() {
return <Hotel43 {...hotel43Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hotel43 } from "@/components/beste/block/hotel43";
export default function Page() {
return (
<Hotel43
eyebrow="Guest book"
heading="What people write on their last morning"
score={{ value: "9.7", scale: "out of 10", note: "From 412 stays since the house reopened" }}
breakdown={[
{ label: "Rooms", value: 9.8 },
{ label: "Breakfast", value: 9.9 },
]}
reviews={[
{ quote: "We came for four nights and changed our ferry twice.", name: "Rhiannon Giddens", detail: "Sea Suite, June" },
{ quote: "The quietest week I have had in years.", name: "Patrick Watson", detail: "Garden Room, September" },
]}
interval={7}
labels={{ previous: "Previous note", next: "Next note", show: "Show note" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small line above the heading |
heading | string | – | Section heading, through Text1 |
score | Score | – | The large overall score with its scale and a note under it |
breakdown | Rating[] | [] | Per-category ratings drawn as hairline bars |
reviews | Review[] | [] | Guest notes shown one at a time |
interval | number | 7 | Seconds each note stays before the next one |
labels | Labels | {} | Accessible names for the arrows and progress buttons |
className | string | – | Extra classes for the outer <section> |
type Score = {
value: string;
scale: string;
note: string;
};
type Rating = {
label: string;
value: number;
};
type Review = {
quote: string;
name: string;
detail: string;
};
type Labels = {
previous?: string;
next?: string;
show?: string;
};scaleX set to value / 10, so values are read on a 10 point scale, and the number beside it is printed with one decimal place.interval seconds and wrap around. The timer does not run with fewer than two reviews or with reduced motion on.breakdown is empty.