Landing Pages

Build landing pages from Markdown using MDC section components.

MDC Section Syntax

Landing pages are built in Markdown using MDC (Markdown Components) syntax. Each section is a Vue component invoked with ::section-name:

content/pages/index.md
---
title: My Product
description: Validate your idea before building it.
---

::section-hero
---
badge: New
badgeIcon: i-lucide-sparkles
headline: Stop Building. Start Validating.
description: Prove demand before writing product code.
---

#cta
  ::convert-form{location="hero" submit-label="Get Early Access"}
  ::
::

::section-benefits
---
headline: Why Founders Choose Us
---
::

::section-faq
---
headline: Common Questions
---
::

How It Works

  1. The landing page uses the landing layout (set via route rules)
  2. ContentRenderer processes the Markdown body
  3. Each ::section-* block resolves to a Vue component in app/components/section/
  4. Props are passed via the YAML block between --- delimiters
  5. Named slots (like #cta) inject child content into specific component slots

Available Sections

These section components are available in the starter. You can override any of them or create new ones.

section-hero

The primary value proposition with headline, description, and CTA.

::section-hero
---
badge: Launch Offer
badgeIcon: i-lucide-rocket
headline: Your Main Headline
description: Supporting description text.
---

#cta
  ::convert-form{location="hero" submit-label="Get Started"}
  ::
::

section-benefits

Feature/benefit grid explaining why your solution matters.

::section-benefits
---
headline: Why This Works
description: Optional supporting text.
---
::

section-outcome

Step-by-step process or outcome visualization.

::section-outcome
---
headline: How It Works
---
::

section-offer

What the visitor gets when they convert. Typically used above the fold or as a mid-page CTA.

::section-offer
---
headline: What You Get
---
::

section-results

Social proof, testimonials, or results.

::section-results
---
headline: What Others Say
---
::

section-faq

FAQ accordion that pulls from the faq content collection.

::section-faq
---
headline: Common Questions
types:
  - technical
  - general
---
::

The types prop filters which FAQ files to include. Omit it to show all.

SectionWrapper

Every section component should use SectionWrapper internally. It provides:

  • Accessibility: aria-labelledby linking to the section heading
  • Testing: data-testid="section-{sectionId}" for automated testing
  • Event tracking: Fires a section_view event when the section enters the viewport (once)

Overriding Sections

To customize a section, create a component with the same name in your app:

app/components/section/Hero.vue    → Overrides the layer's Hero.vue
app/components/section/Custom.vue  → New section, use as ::section-custom

Your component receives all props from the MDC YAML block and has access to named slots.

Nesting Convert Components

Signal capture components can be nested inside sections using MDC:

::section-hero
---
headline: Get Early Access
---

#cta
  ::convert-form{location="hero" submit-label="Join Waitlist" layout="horizontal"}
  ::
::

See Signal Capture for all available convert components.