All posts
9 min read

A Landing Page in Ten Blocks

Not a listicle. This is the anatomy of a complete SaaS landing page built from ten registry blocks: the narrative arc that orders them, the rhythm rules that make them feel like one page, and every section rendered live as we go.

shadcnlanding-pagedesign

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:

  1. Orient: who you are, how to navigate (navbar)
  2. Claim: the one-sentence promise, with immediate credibility (hero)
  3. Substantiate: what it actually does (features, from scannable to deep)
  4. Demonstrate: how it works in practice (process, use cases)
  5. Prove: other people vouch for the claim (testimonials)
  6. Reinforce: why this over the alternatives (differentiators)
  7. Convert: the ask, made at the moment trust peaks (CTA)
  8. 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

Live · Centered Logo Split Nav
View block
Block 1 of 10: navbar30. Symmetric links around a centered logo.

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

Live · Centered Hero with Logo Cloud
View block
Block 2 of 10: hero36. Promise, action, and borrowed credibility in one viewport.

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

Live · Service Grid With Icons
View block
Block 3 of 10: feature3. The scannable pass: every capability, five seconds.

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:

Live · Alternating Rows With Mixed Media
View block
Block 4 of 10: feature2. The deep pass: your two or three real differentiators, with media.

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

Live · Numbered Steps Process
View block
Block 5 of 10: usecase3. Numbered steps turn a product into a plan.

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

Live · Quote Cards Grid
View block
Block 6 of 10: testimonial8. Specific quotes, with the key phrase highlighted.

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

Live · Numbered Reasons List
View block
Block 7 of 10: feature34. The why-us list: numbered, confident, brief.

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

Live · Banner CTA
View block
Block 8 of 10: cta11. The banner: low-commitment, mid-momentum.
Live · Centered Newsletter CTA
View block
Block 9 of 10: cta8. The finale: centered, unhurried, singular.

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

Live · Split Brand Footer
View block
Block 10 of 10: footer10. Brand on the left, exits on the right.

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.

tsx
// 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:

bash
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/footer10

Every 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:

  1. 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.
  2. One rhythm, one scale, one accent. Check it with the squint test before checking anything else.
  3. Alternate density down the page. Two dense sections in a row is a wall; two airy ones is a shrug.
  4. Proof after substance, ask after proof. Light asks earlier, the full stop once.
  5. 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.