Survey syntax reference
Extended Motivation Form field types, media embedding, conditional logic, and page-based pagination — 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.
Pagination with page:
Add a page: integer to any field to control how fields are grouped into pages. There is no separate "survey mode" to enable — the layout is derived entirely from which fields share a page number.
| What you write | What you get |
|---|---|
No page: on any field | All fields on a single page (classic form) |
Fields sharing the same page: value | Those fields appear together on one page |
Each field has a unique page: value | One field per page (classic survey) |
fields:
# Page 1 — two fields grouped together
- id: name
type: text
label: Your name
page: 1
- id: email
type: email
label: Email address
page: 1
# Page 2 — one field alone
- id: recommend
type: nps
label: How likely are you to recommend us?
page: 2
# Page 3 — another field alone
- id: feedback
type: textarea
label: Any other thoughts?
page: 3Page labels
Name each page with page_labels: (list indexed from 0):
page_labels:
- About you
- Satisfaction
- Open feedbackBackward compatibility: The legacy
step:attribute andtype: surveyare still accepted and will continue to work.step:is a direct alias forpage:.type: surveyis treated as assigning each field a unique page automatically. Migrate topage:for new forms.
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, page, 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) |
model3d | .glb / .gltf URL | <model-viewer> web component |
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.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
Each field gets a unique page: number so they appear one at a time.
---
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
page: 1
- 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
page: 2
- id: promoter_reason
type: textarea
label: What do you love most about the product?
show_if:
field: recommend
op: gte
value: 9
page: 2
- 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
page: 3
- 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
page: 4
- id: overall
type: rating
label: Overall, how satisfied are you?
max: 5
page: 5
- id: extra_thoughts
type: textarea
label: Anything else you'd like to share?
required: false
page: 6
---
Thank you for taking this survey. Your feedback shapes the roadmap.