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 progressiontype: 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: 5scale
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 agreenps
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 likelyyes_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
- Documentationmatrix
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 satisfiedstatement
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
- NeitherSupported media types
type | url format | How it renders |
|---|---|---|
image | URL (external) or Supabase Storage URL | <img> with lazy loading |
youtube | Full YouTube URL or 11-char video ID | <iframe> nocookie embed |
video | Direct .mp4 / .webm URL | HTML5 <video> player (no autoplay) |
audio | Direct .mp3 / .wav / .ogg URL | HTML5 <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.pngConditional 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
| Op | Meaning | Works on |
|---|---|---|
eq | equals | any scalar |
neq | does not equal | any scalar |
gt | greater than | number, rating, scale, nps |
lt | less than | number, rating, scale, nps |
gte | greater than or equal | number, rating, scale, nps |
lte | less than or equal | number, rating, scale, nps |
includes | array contains value | checkbox, ranking |
excludes | array does not contain value | checkbox, 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.