Docs navigation
Step types
A flow is an ordered list of Step values. The SDK walks them in declaration order, with two exceptions: a survey reason with an attached offer routes the flow to that offer next, and accepting an offer advances directly to success.
type Step =
| SurveyStep
| OfferStep
| FeedbackStep
| ConfirmStep
| SuccessStep
| CustomStepConfigSurveyStep
interface SurveyStep {
type: 'survey'
guid?: string
title?: string
description?: string
reasons: ReasonConfig[]
classNames?: SurveyClassNames
}guid is an optional stable identifier. Use it when you need analytics to key on the step regardless of its position in the flow.
OfferStep
interface OfferStep {
type: 'offer'
guid?: string
title?: string
description?: string
offer?: OfferConfig | OfferDecision // standalone offer (not routed from a survey reason)
classNames?: OfferClassNames
}Use OfferStep to show an offer outside the survey-reason path — e.g. a pause offer at the start of every flow regardless of reason. copy is optional on the offer; the SDK synthesizes default headline, body, and button text from the offer's display fields. Provide a copy block to override.
FeedbackStep
interface FeedbackStep {
type: 'feedback'
guid?: string
title?: string
description?: string
placeholder?: string
required?: boolean
minLength?: number
classNames?: FeedbackClassNames
}| Field | Behavior |
|---|---|
required: true | The Continue button stays disabled until minLength is met. |
minLength | Character count threshold for Continue to enable. Defaults to 0. |
placeholder | Empty-state hint inside the textarea. |
ConfirmStep
interface ConfirmStep {
type: 'confirm'
guid?: string
title?: string
description?: string
losses?: string[] // bulleted list of features the customer loses
lossesLabel?: string // heading above the loss list. Defaults to "You'll lose access to:"
confirmLabel?: string // defaults to "Cancel subscription"
goBackLabel?: string // defaults to "Go back"
classNames?: ConfirmClassNames
}losses renders as a bullet list above the action buttons. Set it on the step config or, in connected mode, in the dashboard.
The default Confirm reads the subscriptions prop and renders a "Your access continues until X" notice when the active subscription has a currentPeriod.end. The date is formatted in the user's locale via Intl.DateTimeFormat. Override the Confirm component to suppress or restyle.
SuccessStep
interface SuccessStep {
type: 'success'
guid?: string
savedTitle?: string
savedDescription?: string
cancelledTitle?: string
cancelledDescription?: string
classNames?: SuccessClassNames
}Success is terminal. The SDK renders the saved copy when an offer was accepted, the cancelled copy when the customer confirmed.
CustomStepConfig
interface CustomStepConfig {
type: string // any non-built-in string identifies a custom step
guid?: string
title?: string
description?: string
data?: Record<string, unknown>
}Register a component for the type on customComponents. The component receives step, customer, subscriptions, onNext, onBack. See Custom step + offer types.
ReasonConfig
interface ReasonConfig {
id: string
label: string
freeform?: boolean // shows a textarea under the reason list when picked
offer?: OfferConfig // attached offer; presented if the customer picks this reason
}A reason with freeform: true reveals a textarea below the reason list when the customer picks it. The typed text lands on the session as followupResponse, alongside surveyChoiceId (the reason's id) and surveyChoiceValue (the static label) — analytics groupings stay stable on id and label.
Reason IDs land on the session as reasonId on AcceptedOffer and on outcome.reason. Keep them stable — analytics joins on them.
Transitions
The SDK resolves the next step in this order:
- If the current step is a
surveyand the selected reason has anoffer, the next step is that offer. - Otherwise, advance to the next step in
steps. - On
accept, advance directly tosuccess. Intervening steps are skipped. - On
declinefrom an offer step, advance to the next step.
A step with a type that isn't built-in and isn't registered in customComponents logs a console warning and is skipped. The flow never crashes on unknown types.
Connected mode override rules
When the dashboard supplies steps and you also pass steps:
| Server step type | Local step with same type | Result |
|---|---|---|
| Present | Absent | Server step renders. |
| Present | Present | Local overrides by type. |
| Absent | Present | Local step is appended. |
This lets you keep a custom step (like NPS) on every flow regardless of dashboard config.
Next steps
- Offer types — what each offer config carries.
- Customize per-step classNames — the per-type className shapes.
- Custom step + offer types — adding your own step types.