Preview mode
Preview turns the static canvas into a working flow. Buttons navigate, inputs capture text, and toggles flip, so you can walk a screen path the way a user would.Turn preview on
You can toggle preview from two places, and they stay in sync:- The Preview button in the top bar (eye icon). The tooltip shows the shortcut ⌘.
- The Preview button in the floating toolbar at the bottom of the canvas.
What preview does
- Navigation runs. A button wired to
goNext,goBack,navigate, orcloseFlowmoves the canvas to the matching screen, or closes the flow. - Inputs and toggles work. Typing into an input or flipping a toggle updates the bound variable, so any dynamic value driven by that variable updates live.
- It tracks its own screen. Preview keeps a separate “current screen” and a back-history stack. Your editor selection is left untouched, so when you exit preview you land back on whatever screen you were editing.
- It is non-destructive. Preview navigation and any values you change are ephemeral. Nothing here is saved to the flow.
Test branches with variable overrides
Conditional (dynamic) values branch on variables. To see a different branch without manually clicking to the state that sets it, override the variable directly:Open the Variables panel
Open the left Variables tab. While preview is on, a purple Preview badge appears next to the panel title and every variable row becomes an editable override control.
Edit a value
Change a variable’s value. The canvas re-renders immediately so you can see how conditions and interpolated text react. The panel reminds you: “Changes here affect the canvas preview only. They won’t be saved to the flow.”
Preview is an approximation, not the device
Preview is close to the SDK runtime but not identical. Most importantly, actions behave differently here than in a real build. In preview, state and navigation actions run against preview-only state and show a toast instead of doing the real thing (for example, Open URL shows a confirmation rather than leaving the editor). For the full breakdown of which actions fire in edit mode versus preview, see Preview is not the runtime. Always confirm end-to-end behavior on a real build or with live mirror.Move between screens on the canvas
The floating toolbar at the bottom of the canvas has a screen pager you can use in either edit or preview mode:- Previous (left chevron) and Next (right chevron) step through screens in order. The arrow keys ← and → do the same when you are not typing in a field.
- The middle button shows current / total (for example
2/3) and the screen name. Click it to open a list and jump straight to any screen.
Live mirror
Live mirror pairs the editor with a real device so your edits show up on the device in real time. It is the fastest way to judge spacing, fonts, animation timing, and haptics on real hardware.How pairing works
The Live Mirror control is the pill in the top bar, to the left of the schema and Preview buttons. Click it to start.Start mirroring
Click the Live Mirror pill (or Start Mirroring in its popover). The editor opens a WebSocket connection to the FlowPilot backend and asks the server to create a session room. The pill shows Creating room… while it connects.
Get the room code
Once the room is created, the popover shows a QR code and a 6-character room code, with the prompt “Scan this QR code with the FlowPilot app, or enter the code manually.” The pill now reads Waiting for device.
Join from the device
On a device running the FlowPilot preview app, scan the QR code or type in the 6-character code. The QR code encodes a
flowpilot://mirror?code=... deep link, so scanning opens the app straight into the session.Edit and watch
When the device joins, you see a “Device connected” toast and the pill turns green and reads Live · N, where N counts the updates sent. From now on, every edit you make streams to the device automatically.
Connection states
The pill and popover reflect the live session state:| State | Pill label | What it means |
|---|---|---|
| Disconnected | Live Mirror | No session. Click to start. |
| Connecting | Creating room… | Opening the WebSocket and creating the room. |
| Connected | Waiting for device | Room is ready; QR code and code are shown; no device yet. |
| Streaming | Live · N | A device is connected and receiving your edits. |
| Error | Error | The connection failed. The popover offers Retry. |
Notes and warnings
Live mirror needs network connectivity to the FlowPilot backend WebSocket hub from both the editor and the device. If the device cannot reach the backend, it will not join the room.
Common mistakes
- Expecting preview to match the device exactly. Preview is an approximation. Action behavior, in particular, differs from a real build. Use live mirror or a real SDK build to confirm.
- Confusing the preview app with your production integration. The FlowPilot preview app is a QA tool for mirroring. Your app ships flows through the SDK after you publish and attach to a placement.
- Testing a published flow in preview and assuming users see it. Preview and mirror always show the current draft in the editor. Users only see a flow once it is published and attached to a placement.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Preview button does nothing visible | The flow has one screen and no wired navigation | Add a second screen and a button with a goNext action, then preview again. |
| A wired button does not switch screens while authoring | You are in edit mode, where navigation actions do not fire | Enter preview mode (⌘.), then click the button. |
| Mirror pill stuck on Waiting for device | No device has joined the room | Scan the QR code or enter the 6-character code in the FlowPilot preview app. Codes and rooms expire after about 5 minutes of inactivity; restart mirroring to get a fresh code. |
| Mirror shows Error | The editor could not reach the backend WebSocket hub | Check network connectivity, then click Retry in the popover. |
| Device joined but edits do not appear | The device dropped its connection | Confirm the pill still reads Live; if it fell back to Waiting for device, rejoin from the device. |