A blog section splitting a bordered container between the newsletter pitch with a cadence line on a hairline and an image tile holding a working subscribe row, over three linked back issues.
A blog section splitting a bordered container between the newsletter pitch with a cadence line on a hairline and an image tile holding a working subscribe row, over three linked back issues.
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/blog62?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/blog62?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/blog62.tsx, the form36 subscribe piece it holds in the tile (installed to components/beste/piece/form36.tsx), and the badge23 component it uses for the eyebrow.
The installed file exports blog62Demo alongside the block: the exact props behind the preview above. Spread it to get a working panel in one line.
import { Blog62, blog62Demo } from "@/components/beste/block/blog62";
export default function NewsletterPage() {
return <Blog62 {...blog62Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Blog62 } from "@/components/beste/block/blog62";
import { Form36 } from "@/components/beste/piece/form36";
export default function NewsletterPage() {
return (
<Blog62
badge={{ label: "The monthly note" }}
heading="One letter a month about running a practice well"
description="What we shipped, what we got wrong, and one long piece of writing."
media={
<Form36
label="Join the monthly note"
placeholder="you@practice.com"
submitLabel="Subscribe"
finePrint="Unsubscribe from the footer of any issue."
/>
}
image={{ src: "/backdrops/blue.jpg", alt: "Soft blue gradient backdrop" }}
cadence="2,140 practice leads · first Tuesday · 12 issues so far"
posts={[
{
category: "Issue 12",
title: "The month we stopped counting tickets",
excerpt: "Support volume is a symptom, not a metric.",
date: "May 2026",
href: "/newsletter/12",
},
{
category: "Issue 11",
title: "Every field we deleted this quarter",
excerpt: "Thirty-one inputs left the product, and two had to come back.",
date: "April 2026",
href: "/newsletter/11",
},
]}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow at the top of the pitch column |
heading | string | – | Panel heading |
description | string | – | Supporting paragraph, capped at max-w-md |
media | ReactNode | – | Subscribe row on the tile, form36 in the demo |
image | { src: string; alt: string } | – | Backdrop behind the media tile |
cadence | string | – | Subscriber and frequency line under a hairline |
posts | CompactPost[] | [] | Linked back issues under the panel |
className | string | – | Extra classes for the outer section |
type TileImage = {
src: string;
alt: string;
};
type CompactPost = {
category: string;
title: string;
excerpt: string;
date: string;
href: string;
};Badge23 carries self-start here, which is load-bearing. The column is a flex flex-col, and an inline-flex badge inside it would otherwise stretch to the full column width.overflow-hidden clips it to the panel's corner, which is what makes the tile read as half of one box rather than a picture placed inside it.h-64 below md and switches to md:h-auto md:min-h-80, so it matches the pitch column's height on desktop while keeping a sensible band height on mobile.cadence carries its own border-t and top padding, so the rule only appears when the line is passed.Link elements in a flex flex-col with the excerpt marked flex-1, so the date lines up along the bottom across all three columns regardless of excerpt length.border-t, so the rules are per column and stop at the gaps.form36 piece. This block holds no form state and has no submit handler.Wiring the form up
The subscribe row is a presentational piece with no submit handling of its own. When you connect it to a real list, the patterns in React Hook Form, TanStack Form, and Formisch cover validation and submission for this shape of single-field form.
blog46
A newsroom front page with a heading, a divider, and a square eyebrow over a hairline rule, a wide lead story whose headline and standfirst split across a twelve column band under a panoramic image, and the remaining articles set as three bordered text cards.
blog14
Four-column grid mixing blog cards with an integrated newsletter signup card. Email input and subscribe button embedded in the layout.
blog43
A blog listing with an eyebrow over a hairline rule, a two-column heading, and three linked article cards with a hover-zoom image, a category label, a title, an excerpt, and byline.
blog52
A CSS-columns masonry of linked newsroom cards under a parenthetical eyebrow and a large heading, where the image aspect ratio cycles by position so the wall keeps an uneven, magazine-like rhythm.