Marketing sections
What a band of a landing page is made of, and why these take data rather than markup.
The marketing components are the bands a landing page is built from: a hero, a wall of features, what customers said, what it costs, and the closing call to action. They are compositions rather than primitives, so what matters about them is not their padding but the three decisions each one encodes.
One band, three parts
Every band is assembled from the same three kinds of part, though not every band has all three:
| Part | Prop | What it is for |
|---|---|---|
| The heading block | eyebrow, title, description, and the two options that place it: titleAs, headingSize |
What this band is about, and where its heading sits in the page's outline |
| The body | items, media, features |
The repeated thing: features, quotes, plans, a picture |
| The actions | primaryAction, secondaryAction |
What the reader can do now, on Hero, CTA and PricingCard; the feature grid and the testimonials have no action pair, and take anything actionable through children |
The heading block is the framework's own SectionHeading, so the eyebrow, the alignment, the level
and the size behave the same in all five bands. title is the one part most of them require:
a band with no heading is a band a reader cannot find on a long page.
Data, not markup
The body is an array of values, not a pile of nodes:
<FeatureGrid
title="Everything in one place"
items={[
{ icon: <InvoiceIcon />, title: "Invoicing", description: "Issue and chase." },
{ icon: <ContactsIcon />, title: "Contacts", description: "One list, deduplicated." },
]}
/>
That is deliberate, and it is the reason these components exist at all. An array can be serialised,
so a visual builder can store it; it can be rendered by the platform's own primitives, so the same
band works on a device; and the band keeps control of its own layout instead of negotiating with
whatever markup the consumer passed. The types are exported (FeatureItem, TestimonialItem,
PricingFeatureItem), so a page describes its content once and passes it.
It also means the components can decide things a consumer would otherwise have to remember: a
FeatureItem with an href becomes a link, and a PricingFeatureItem with included: false is
drawn as excluded rather than omitted.
Actions are configuration too
ActionConfig is the same idea applied to the buttons. label is the only required field, and every
other field maps onto a Button prop, so a configured action renders exactly like one you wrote by
hand:
primaryAction={{ label: "Start free", href: "/signup" }}
secondaryAction={{ label: "Read the docs", href: "/docs", variant: "bordered" }}
The emphasis is the band's decision, not yours: a primary action is solid and a secondary one is bordered unless the config states otherwise. That is what keeps a page's bands consistent when different people write them.
One consequence worth knowing before you plan around it: ActionConfig has no onClick. A configured
action either navigates (href, or component for a router link) or it does not act on its own, an
action that has to open a dialog or submit something belongs in the band's children, where you can
render a Button with its own handler.
The layout axes
Each band takes the options its shape needs, and they are the vocabulary the rest of the library uses (see Layout and spacing):
| Band | Its axes |
|---|---|
| Hero | mediaPosition: where the picture sits relative to the words |
| FeatureGrid | columns, columnsMd, columnsLg, gap, the grid's column scale |
| Testimonials | The same column and gap vocabulary |
| PricingCard | variant, size |
| CTA | panel: whether the closing call sits on its own surface |
How they compose a page
These bands are the content of a MarketingLayout, which supplies the navigation slot, the footer slot and the page background. The layout is the page; the bands are what you put in it.
One rule that outranks the rest: a page has one <h1>. Every band renders its heading as an
<h2> by default, at every size, headingSize moves the treatment, never the level, so the page
supplies the <h1> itself, in whatever heading it places above the bands, or one band states
titleAs="h1", which is what a landing page whose hero is the page title does. Every other band
stays at h2, and if a band's level does not match the page it is dropped into, the page's outline
is wrong even though each band looks right on its own.