Multi-Step Forms
Long forms are easier to complete when they are broken into manageable pieces. The layout property chooses how a form's fields are presented: all at once, split into steps with previous/next navigation, or one field per screen Typeform-style. Steps support conditional skipping and branching so the path through the form can adapt to the submitter's answers.
forms:
- id: 1
name: onboarding
title: Set up your workspace
layout: multi-step
submitTo: { table: workspaces }
fields:
- { kind: standalone, name: workspace_name, inputType: short-text, required: true }
- { kind: standalone, name: team_size, inputType: number }
- { kind: standalone, name: use_case, inputType: long-text }
steps:
- { id: basics, title: The basics, fields: [workspace_name] }
- { id: team, title: Your team, fields: [team_size] }
- { id: goals, title: Your goals, fields: [use_case] }
Layout Modes
| Mode | Description |
|---|---|
single-page |
All fields on one page (default). Steps are ignored. |
multi-step |
Fields grouped into steps[] with previous/next navigation. |
one-question |
One field per screen, advancing automatically. Driven by the same steps[] model. |
Step Definitions
When layout is multi-step or one-question, the steps array partitions the form's fields into ordered screens. Each step references field names defined in the parent fields array.
| Property | Description |
|---|---|
id |
Unique step id within the form (kebab-case recommended, ≤64 chars). Required. |
title |
Step title shown above the fields. |
description |
Step intro paragraph. |
fields |
Field names belonging to this step. Each must match a field's name (standalone/calculation/signature) or column (table-field). At least one. |
visibleWhen |
Whole-step visibility rule. When false, the entire step is skipped. Uses the conditional shape. |
goToWhen |
Branching rules. The first matching rule jumps to its goTo step instead of the linear next step. |
Navigation & Branching
By default a multi-step form advances linearly: step 1 → step 2 → step 3. Two mechanisms override that flow.
Skip a step with a step-level visibleWhen — when the condition is false the step is removed from the sequence entirely.
Branch to a different step with goToWhen. Each rule has a when condition and a goTo target step id; the first matching rule wins, otherwise linear flow continues.
steps:
- id: plan
title: Choose a plan
fields: [plan]
goToWhen:
# Enterprise plans skip self-serve billing and route to a sales step
- when: { field: plan, operator: eq, value: enterprise }
goTo: sales
- id: billing
title: Payment
fields: [card_number]
- id: sales
title: Talk to sales
fields: [company, seats]
# only relevant for enterprise; hidden otherwise
visibleWhen: { field: plan, operator: eq, value: enterprise }
goTo targets must exist. Each goToWhen[].goTo must match a steps[].id in the same form. A linear next step is taken whenever no goToWhen rule matches.
One-Question-at-a-Time
The one-question layout presents a single field per screen for a focused, conversational experience. It reuses the same steps[] model — typically one field per step — and the same visibleWhen / goToWhen branching applies.
forms:
- id: 2
name: survey
title: Quick survey
layout: one-question
submitTo: { storeSubmission: true }
display:
progressBar: true
fields:
- {
kind: standalone,
name: nps,
inputType: rating,
label: How likely are you to recommend us?,
}
- {
kind: standalone,
name: reason,
inputType: long-text,
label: What's the main reason for your score?,
}
steps:
- { id: q1, fields: [nps] }
- { id: q2, fields: [reason] }
Display Overrides
The display object adjusts how the form looks without affecting submission semantics.
| Property | Description |
|---|---|
columns |
Number of columns the fields are arranged in (1–4). Applies to single-page and per-step layouts. |
progressBar |
Show a progress bar in multi-step / one-question layouts. No effect on single-page. |
submitLabel |
Submit button label (Submit by default). Supports $t: keys. |
theme |
Per-form overrides: primaryColor, backgroundColor, borderRadius. |
forms:
- id: 3
name: registration
title: Event registration
layout: multi-step
display:
columns: 2
progressBar: true
submitLabel: Complete registration
theme:
primaryColor: '#4f46e5'
borderRadius: 0.5rem
submitTo: { table: registrations }
fields:
- { kind: table-field, column: first_name, required: true }
- { kind: table-field, column: last_name, required: true }
- { kind: table-field, column: email, required: true }
- { kind: table-field, column: dietary_notes }
steps:
- { id: name, title: Your name, fields: [first_name, last_name] }
- { id: contact, title: Contact & preferences, fields: [email, dietary_notes] }
Related Pages
- Form Fields — the fields distributed across steps.
- Conditional Logic — the condition shape used by
visibleWhenandgoToWhen. - Forms Overview —
layout,steps, anddisplayin the full form schema. - Submissions — what happens after the final step.