Skip to main content
A custom screen replaces a whole screen in a flow with your own native SwiftUI view, while the screen still lives inside the flow’s navigation. Where a custom component is one element on a screen, a custom screen is the entire screen. The intended use is a fully native step such as a paywall or a permissions prompt that still emits events to advance the flow.
Status: the registration API on this page is real and public, but in the current SDK build custom screens are not yet rendered. The SDK stores the registered definition but does not yet render it. There is also no editor authoring path: the editor schema has no custom-screen concept, so flows cannot reference a custom screen today.Treat this as a roadmap API. For native UI inside a flow now, use a custom component, which is fully wired. This page documents the SDK surface for completeness and will be updated when the render path and editor authoring land.

The SDK API

Registration mirrors custom components, keyed by a screen identifier:
CustomScreenDefinition declares inputs, outputs, and the factory:

Reading inputs

CustomScreenParams exposes the resolved inputs with the same typed accessors as a component:

The screen context

CustomScreenContext lets the screen emit events and control the persistent zones drawn over it:
  • emit works like a custom component’s emit: the named event enters the flow’s interaction system for the flow to act on. The name should match a declared output.
  • setZonesVisible(_:) shows or hides the flow’s persistent UI (the nav bar, footer, and overlay zones) over your native screen. See Persistent UI (zones).
  • setChromeVisible(_:) is deprecated and simply forwards to setZonesVisible(_:). Use setZonesVisible(_:).

Example

How a custom screen would be registered once the render path is active. A native paywall that emits purchased to advance the flow:
In the editor (when supported), you would wire the purchased event to a goNext action so the flow moves to the next screen after the purchase.

Common mistakes

  • Expecting it to render today. It will not. The registration succeeds but the SDK does not yet draw custom screens. Use a custom component instead.
  • Same contract pitfalls as components. When this ships, the screen identifier, input keys, and event keys must match between the editor and the SDK.
  • Forgetting to advance the flow. A custom screen that never emits an event leaves the user stuck on a native screen with no way forward. Always emit an event that a flow action can act on.
  • Using setChromeVisible. It is deprecated. Call setZonesVisible(_:).