Motivation Form

Survey syntax reference

Extended Motivation Form field types, media embedding, conditional logic, and survey mode — all via .md frontmatter.

This page covers the extended syntax available in Motivation Form .md files beyond the core 10 field types. Use these when you are building surveys, NPS studies, A/B comparisons, or any form where standard text/choice inputs are not enough.

The core 10 types (text, email, textarea, number, radio, checkbox, select, date, image, file) remain unchanged and are documented in Field types.


Form vs. survey mode

type: form    # default — all fields on one page (or multi-step with `step:`)
type: survey  # one field at a time, full-screen, linear progression

type: survey switches the renderer to a single-question-at-a-time layout with a large prompt and a prominent "Next" button. All other frontmatter keys (fields, branding, notifications, etc.) work identically in both modes.


Global settings

settings:
  progress_bar: true          # show a progress bar at the top (default: false)
  randomize_options: true     # shuffle option order for radio/checkbox/select/ranking (default: false)

New field types

All fields share the common properties (id, label, required, help_text, step, show_if).

rating

Star (or emoji) rating. Response value: integer 1–max.

- id: overall_experience
  type: rating
  label: How would you rate your overall experience?
  max: 5        # 1–10 supported; default: 5

scale

Labelled numeric scale (Likert-style). Response value: integer.

- id: ease_of_use
  type: scale
  label: This product is easy to use.
  min: 1
  max: 7
  min_label: Strongly disagree
  max_label: Strongly agree

nps

Net Promoter Score. Renders as 11 numbered buttons (0–10) with anchors. Response value: integer 0–10.

- id: recommend
  type: nps
  label: How likely are you to recommend us to a colleague?
  low_label: Not at all likely
  high_label: Extremely likely

yes_no

Binary choice. Response value: "yes" or "no".

- id: used_before
  type: yes_no
  label: Have you used a similar product before?

ranking

Drag-and-drop ordered list. Response value: ordered array of option strings.

- id: priority_order
  type: ranking
  label: Rank these features by importance to you.
  options:
    - Speed
    - Price
    - Reliability
    - Customer support
    - Documentation

matrix

Grid of rows × columns. Each row is one question; columns are the shared response options. Response value: { row_id: selected_column } object.

- id: satisfaction_grid
  type: matrix
  label: Rate each aspect of the product.
  rows:
    - id: onboarding
      label: Onboarding experience
    - id: performance
      label: Performance
    - id: docs
      label: Documentation
  columns:
    - Very dissatisfied
    - Dissatisfied
    - Neutral
    - Satisfied
    - Very satisfied

statement

Read-only informational block. No user input. Use for section headings, instructions, or consent text within a multi-step form. Not included in the response payload.

- id: intro_text
  type: statement
  label: "Before you begin"
  help_text: |
    This survey takes about 3 minutes. Your responses are anonymous
    and will only be used to improve the product. Thank you.

Media embedding

Any field can display rich media above its input with the media: property. Media is for display only — it does not affect the response value.

- id: logo_preference
  type: radio
  label: Which logo do you prefer?
  media:
    type: image
    url: https://cdn.example.com/logo-options.png
    alt: Two logo concepts for the rebrand.   # optional
  options:
    - Option A
    - Option B
    - Neither

Supported media types

typeurl formatHow it renders
imageURL (external) or Supabase Storage URL<img> with lazy loading
youtubeFull YouTube URL or 11-char video ID<iframe> nocookie embed
videoDirect .mp4 / .webm URLHTML5 <video> player (no autoplay)
audioDirect .mp3 / .wav / .ogg URLHTML5 <audio> player
document.pdf URL (or any document URL)Supabase/same-origin PDFs embed inline; external PDFs and other docs show an open-in-new-tab card
model3d.glb / .gltf URL<model-viewer> web component

All media types accept optional title (shown above) and caption (shown below) in addition to alt.

image

media:
  type: image
  url: https://cdn.example.com/comparison.png
  alt: Before and after redesign.

youtube

media:
  type: youtube
  url: https://www.youtube.com/watch?v=dQw4w9WgXcQ
  alt: Product walkthrough (2 min).

video

media:
  type: video
  url: https://cdn.example.com/demo.mp4
  alt: Click play to watch the demo before answering.

audio

media:
  type: audio
  url: https://cdn.example.com/clip.mp3
  title: Listen before answering
  caption: 12-second support call excerpt.

document

PDFs hosted on Supabase Storage (or same-origin) render in an inline viewer; external PDFs and any other document URL render as an open-in-new-tab card (the app's CSP only frames trusted hosts). Set height to control the inline PDF viewer height (default 480px).

media:
  type: document
  url: https://cdn.example.com/spec.pdf
  title: Draft specification
  height: 600
  caption: Review section 3 before responding.

model3d

media:
  type: model3d
  url: https://cdn.example.com/product.glb
  alt: Drag to rotate the 3D model.

Media on individual options

For visual A/B comparisons, attach media: to individual options. When any option in a radio or checkbox field has a media: key, the field renders as a visual card grid instead of a text list.

- id: design_preference
  type: radio
  label: Which design direction resonates most?
  options:
    - label: Minimal
      media:
        type: image
        url: https://cdn.example.com/design-a.png
    - label: Bold
      media:
        type: image
        url: https://cdn.example.com/design-b.png
    - label: Playful
      media:
        type: image
        url: https://cdn.example.com/design-c.png

Conditional logic

Show or hide any field based on the current value of another field with show_if:.

show_if:
  field: <other_field_id>
  op: eq | neq | gt | lt | gte | lte | includes | excludes
  value: <scalar or string>

The field is hidden on page load and revealed client-side when the condition is met. Hidden fields are excluded from the submitted payload.

Operators

OpMeaningWorks on
eqequalsany scalar
neqdoes not equalany scalar
gtgreater thannumber, rating, scale, nps
ltless thannumber, rating, scale, nps
gtegreater than or equalnumber, rating, scale, nps
lteless than or equalnumber, rating, scale, nps
includesarray contains valuecheckbox, ranking
excludesarray does not contain valuecheckbox, ranking

Examples

# Show follow-up only for detractors (NPS 0–6)
- id: detractor_reason
  type: textarea
  label: What would need to change for you to rate us higher?
  show_if:
    field: recommend
    op: lte
    value: 6

# Show feature request field only when "New feature" is checked
- id: feature_detail
  type: textarea
  label: What feature would you like?
  show_if:
    field: feedback_type
    op: includes
    value: New feature

# Show competitor name only when respondent says they use another product
- id: competitor_name
  type: text
  label: Which product do you use today?
  show_if:
    field: uses_competitor
    op: eq
    value: "yes"

Complete survey example

---
type: survey
title: Product Experience Survey
slug: product-survey
settings:
  progress_bar: true
branding:
  primary_color: "#6366f1"
notifications:
  email:
    - team@example.com
fields:
  - id: recommend
    type: nps
    label: How likely are you to recommend us to a colleague?
    low_label: Not at all likely
    high_label: Extremely likely
    required: true

  - id: detractor_reason
    type: textarea
    label: What would need to change for you to rate us higher?
    show_if:
      field: recommend
      op: lte
      value: 6

  - id: promoter_reason
    type: textarea
    label: What do you love most about the product?
    show_if:
      field: recommend
      op: gte
      value: 9

  - id: ease_of_use
    type: scale
    label: The product is easy to use.
    min: 1
    max: 5
    min_label: Strongly disagree
    max_label: Strongly agree

  - id: top_feature
    type: ranking
    label: Rank these features by how much you rely on them.
    options:
      - CLI / MCP integration
      - Email notifications
      - Response dashboard
      - Branding options
      - File uploads

  - id: overall
    type: rating
    label: Overall, how satisfied are you?
    max: 5

  - id: extra_thoughts
    type: textarea
    label: Anything else you'd like to share?
    required: false
---

Thank you for taking this survey. Your feedback shapes the roadmap.

On this page