Marketing Site Component Libraries
Why Marketing Sites Need Their Own Design System Discipline
Product teams have largely accepted component libraries and design systems as standard practice, but marketing sites — built faster, iterated more aggressively, and often by a rotating cast of contractors and agencies — frequently skip this discipline entirely. The result is dozens of near-duplicate hero sections, inconsistent button styles, and CSS that only one departed contractor ever understood. A component library for the marketing site applies the same engineering discipline: a constrained set of well-tested, reusable building blocks that both compose consistently and render fast.
Marketing Components Differ From Product Components
A product app's component library (buttons, inputs, modals) optimizes for functional consistency across dense UI. A marketing site's components optimize for something slightly different: visual impact, copy flexibility, and conversion performance. A 'Hero' component on a marketing site needs to support dramatically different visual treatments (video background, gradient, static image, split-layout) while keeping the underlying markup semantically consistent and accessible. This often means marketing component libraries lean more heavily on variant props and slot-based composition than a typical product design system does.
type HeroVariant = "video-bg" | "split-image" | "gradient" | "minimal";
interface HeroProps {
variant: HeroVariant;
headline: string;
subhead?: string;
cta: { label: string; href: string };
media?: { type: "video" | "image"; src: string; alt?: string };
}
export function Hero({ variant, headline, subhead, cta, media }: HeroProps) {
return (
<section className={`hero hero--${variant}`} data-variant={variant}>
<div className="hero__content">
<h1>{headline}</h1>
{subhead && <p className="hero__subhead">{subhead}</p>}
<a
href={cta.href}
className="hero__cta"
data-analytics-id="hero_cta_click"
>
{cta.label}
</a>
</div>
{media?.type === "image" && (
<img src={media.src} alt={media.alt ?? ""} loading="eager" fetchPriority="high" />
)}
{media?.type === "video" && (
<video autoPlay muted loop playsInline poster={media.src + "-poster.jpg"}>
<source src={media.src} type="video/mp4" />
</video>
)}
</section>
);
}Bake Analytics Attributes Into the Component, Not Into Every Page
data-analytics-id attribute on the CTA above. Baking a consistent data attribute convention into shared components means GTM triggers can target [data-analytics-id] generically across the entire site, instead of marketers or developers manually wiring up a new GTM click trigger for every individual page's CTA button — a huge source of tracking drift and missed events on marketing sites.Governance: Who Can Add a New Variant?
Without governance, 'just add a variant prop' becomes an ever-growing pile of one-off styles masquerading as a design system. Effective marketing component libraries set a clear bar: a genuinely new layout need justifies a new variant; a one-off color tweak for a single campaign does not, and should be handled via a theming/token override instead of a new component branch. Pair this with a living Storybook (or equivalent) instance that both designers and marketers can browse, so the question 'does a component like this already exist' has a visible answer before anyone builds a duplicate.
Sharing Components Between Marketing Site and Product App
When the marketing site and product app share a monorepo (common with Next.js + Turborepo setups), it's tempting to share the entire component library. In practice, share only the truly brand-level primitives — design tokens, typography scale, color palette, base button/input styles — and keep marketing-specific layout components (heroes, pricing tables, testimonial grids) separate. Product UI and marketing UI have different performance budgets, accessibility requirements, and iteration speed; forcing full component sharing usually creates friction in both directions.
Component Libraries Can Become a Performance Trap Too
What's Next?
With a disciplined component system in place, the natural next step is using it to actually run controlled experiments — which raises its own rendering-strategy questions.
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.