Assembling a landing page from pre-built sections has a bad reputation, and the reputation is earned. Most assembled pages look assembled: five sections with five different personalities, spacing that lurches between cramped and cavernous, three competing accent colors, and a CTA that shows up before anyone has a reason to click it.
None of that is caused by using blocks. It's caused by skipping the two layers of thinking that sit above any individual section: the narrative arc (what order sections go in, and why) and the system rules (what makes ten independent components read as one page). This post builds a complete SaaS landing page from ten blocks and explains both layers as we go. Every section below is rendered live, full-width, exactly as it ships.
The arc before the blocks
A landing page is an argument. It has a shape, and the shape barely changes across products:
- Orient: who you are, how to navigate (navbar)
- Claim: the one-sentence promise, with immediate credibility (hero)
- Substantiate: what it actually does (features, from scannable to deep)
- Demonstrate: how it works in practice (process, use cases)
- Prove: other people vouch for the claim (testimonials)
- Reinforce: why this over the alternatives (differentiators)
- Convert: the ask, made at the moment trust peaks (CTA)
- Ground: the exits for people not ready to buy (footer)
Ten blocks, eight beats. Two beats get two blocks each because substantiation and conversion both benefit from a second pass at a different altitude. Everything that follows maps to this arc, and when you swap any block for an alternative, the beat it serves stays the same.
System rules: what makes ten blocks one page
Before the first section, the three rules that hold the page together. They're boring, which is why they work.
One vertical rhythm. Every section owns its whitespace with the same padding scale, py-24 at desktop, and no section adds outer margins. Consistent internal padding is what makes stacking arbitrary sections safe: any block above, any block below, the gap is always right.
One type scale, one accent. Section headings live at text-3xl/text-4xl, body copy at text-base/text-lg in text-muted-foreground, and exactly one color is allowed to mean "act here": --primary. When every block draws from the same CSS variables, cohesion isn't an act of discipline. It's the default, and diverging would take effort.
Alternate density. A page of dense grids exhausts. A page of airy heroes says nothing. The arc below deliberately alternates: airy hero, dense grid, spacious rows, structured steps, dense quotes, spacious list. The alternation is what creates the feeling of pacing.
The squint test
Zoom your finished page out to 25% and squint. You should see an even column of alternating light and dense bands with a single color recurring down the page. If one band is twice as tall as its neighbors or a second accent color appears, you've found your fix before a single user has.
Now, the page. Top to bottom.
Beat 1: Orient
The navbar's job on a landing page is smaller than it looks: signal the brand, expose three to five anchors, and stay out of the hero's way. A centered-logo layout does one extra thing for you: symmetry reads as calm, which suits the airy hero that follows. Resist the mega menu here. Mega menus are for products with surface area to browse; a landing page has an argument to make, in order.
Beat 2: Claim
The hero carries three jobs in one viewport: the promise (heading), the action (CTA pair), and the first proof (logo cloud). That last one matters more than its size suggests. A visitor's first skeptical question isn't "what does it do", it's "is this real". Logos answer it before it's asked, which is why a hero with a built-in logo cloud beats a hero plus a separate logo section: same content, one fewer seam, and the proof arrives while the promise is still on screen.
Note the CTA pair convention: one solid primary action, one ghost secondary. Two solid buttons compete; two ghosts whisper. This pattern repeats at every conversion point on the page, and the repetition itself is a system rule: by the third time, the visitor's eye knows exactly what "the action" looks like.
Beat 3: Substantiate, twice
Feature sections fail in two opposite ways: the wall of twelve identical cards nobody reads, and the single deep-dive that buries breadth. The fix is two passes at different altitudes. First, the scannable grid: every capability as an icon, a title, and one sentence. A visitor gets the full surface area in five seconds of scanning.
Then, immediately after, drop altitude:
Alternating image-and-text rows are where your two or three actual differentiators get room: a real screenshot, a real workflow, a paragraph instead of a sentence. The grid said "we have everything you need"; the rows say "and here's the part nobody else has". Same beat, two altitudes, and the density alternation (dense grid, spacious rows) is doing the pacing work described above.
Beat 4: Demonstrate
Features describe the product; a process section describes the visitor's next month. Numbered steps do something subtle: they convert "should I buy this" into "step one looks easy". Three or four steps, each with a concrete outcome. If your onboarding genuinely takes ten steps, this section is lying and your product has a different problem; the block can't fix that, and shouldn't try to hide it.
Beat 5: Prove
Testimonials work in proportion to their specificity. "Great product, highly recommend" proves only that someone was polite. "Cut our deploy time from 40 minutes to 6" proves the claim your hero made. This grid supports inline highlighting for exactly that reason: bold the number, the outcome, the phrase that echoes your promise. Placement matters too: proof belongs after substance, once the visitor knows what's being vouched for, and before the ask.
Beat 6: Reinforce
By this point the visitor knows what you do, how it works, and who vouches for it. The numbered reasons list answers the one remaining question: "why this one and not the tab I have open next to it". Notice what this block is not: it's not another feature grid. Features describe capability; reasons describe choice. Keep each one to a sentence and let the numbers carry the confidence.
Beat 7: Convert, twice
Two CTAs is not repetition; it's two different visitors. The banner catches the convinced-early reader with a compact, inline ask that doesn't interrupt momentum. The centered finale is for the reader who made it through the whole argument: generous whitespace, one heading, one action. This is also where the accent-color discipline pays off: because --primary has only ever meant "act", both CTA sections inherit maximum signal without raising their voice.
The most common assembly mistake
Placing the big CTA right after the hero. A conversion ask before substantiation converts only the people who arrived pre-sold, and it teaches everyone else to scroll past your buttons. The ask goes where trust peaks: after proof, before the footer. Earlier asks should be light (a banner, a nav button), not the full stop.
Beat 8: Ground
The footer is for the visitor who isn't converting today: docs, pricing, contact, the links that keep the tab alive. A split layout restates the brand once (left) and organizes the exits (right). It's also the quietest place on the page by design; if your footer competes with your CTA, one of them is mis-weighted.
The whole page as code
Here's what the assembled page actually looks like. This is the part that surprises people who haven't used registry blocks: the composition layer is trivially small, because every block is a self-contained section taking plain-data props.
// app/page.tsx
import { Navbar30 } from "@/components/beste/navbar30";
import { Hero36 } from "@/components/beste/hero36";
import { Feature3 } from "@/components/beste/feature3";
import { Feature2 } from "@/components/beste/feature2";
import { Usecase3 } from "@/components/beste/usecase3";
import { Testimonial8 } from "@/components/beste/testimonial8";
import { Feature34 } from "@/components/beste/feature34";
import { Cta11 } from "@/components/beste/cta11";
import { Cta8 } from "@/components/beste/cta8";
import { Footer10 } from "@/components/beste/footer10";
export default function Page() {
return (
<>
<Navbar30 {...navbar30Demo} />
<main>
<Hero36 {...hero36Demo} />
<Feature3 {...feature3Demo} />
<Feature2 {...feature2Demo} />
<Usecase3 {...usecase3Demo} />
<Testimonial8 {...testimonial8Demo} />
<Feature34 {...feature34Demo} />
<Cta11 {...cta11Demo} />
<Cta8 {...cta8Demo} />
</main>
<Footer10 {...footer10Demo} />
</>
);
}Every block ships with a <name>Demo props object exported from the same file, holding exactly the content you saw in the previews above. Spread it to get a working page on the first render, then replace the demo objects with your own copy one section at a time. The page never passes through a broken in-between state, which makes this the fastest honest way to go from empty repo to reviewable draft.
And the install is one command per block:
npx shadcn add https://ui.beste.co/r/navbar30 https://ui.beste.co/r/hero36 \
https://ui.beste.co/r/feature3 https://ui.beste.co/r/feature2 \
https://ui.beste.co/r/usecase3 https://ui.beste.co/r/testimonial8 \
https://ui.beste.co/r/feature34 https://ui.beste.co/r/cta11 \
https://ui.beste.co/r/cta8 https://ui.beste.co/r/footer10Every block above is free, and every one arrives as editable source in your repo. If the deep-dive rows need a video instead of an image, or the steps need a fourth entry, those are edits to files you own, not feature requests to a library.
The checklist, compressed
When you assemble your own ten:
- Map blocks to beats, not to categories. You're not picking "a features section"; you're picking the scannable pass and the deep pass of the substantiate beat.
- One rhythm, one scale, one accent. Check it with the squint test before checking anything else.
- Alternate density down the page. Two dense sections in a row is a wall; two airy ones is a shrug.
- Proof after substance, ask after proof. Light asks earlier, the full stop once.
- Swap blocks freely within a beat. A carousel testimonial serves beat five exactly as well as a quote grid; the arc doesn't care, so pick for your content's shape.
The blocks are interchangeable. The argument isn't.