type: "custom", the React Native and Flutter SDKs call your customScreenBuilder.
On SDKs that expose customScreenBuilder, the builder receives a context object with:
ctx.formData: the data already collected in the flowctx.screenData: the JSON for the current custom screenctx.onNext(): move to the next screenctx.onPrevious(): move to the previous screenctx.onFinish(): end the flowctx.onJumpTo(screenId): jump to another screen in the same flow
Basic flow shape
In Flowboard, the screen itself stays part of the same flow. You only replace the rendering for that one step.Simple example
Start with oneif and one custom screen. This is the easiest way to understand the lifecycle.
The native iOS example above is a workaround. It launches your own UIKit surface from a custom action, but it does not replace a Flowboard
type: "custom" screen inside the flow because that API is not yet exposed in the Swift package.Recommended production setup
For production, keep yourcustomScreenBuilder small and route by screen ID in one place.
This gives you a single entry point, keeps launch code clean, and makes each custom screen easier to test.
Recommended structure:
- Put the router in one dedicated file
- Use a
switchonscreenId - Load each custom screen from its own file
- Keep a fallback screen for unknown IDs
Adjust the example file paths to match your app structure. The important part is the separation between the router and the screen components. On native iOS, keep the same router idea, but route to your own presented UIKit or SwiftUI surfaces from
onCustomAction(...).Practical guidance
Use custom screens for cases like:- A native paywall tied to your purchase SDK
- A login or signup screen backed by your own auth flow
- A profile summary or confirmation step based on earlier answers
- A screen that depends on native features not exposed by standard Flowboard components