Workflow Module
The Workflow module runs server-driven multi-step workflows where step ordering and configuration come from the backend per session. Unlike the
This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation here. We strongly recommend upgrading - contact your Incode Representative for upgrade information.
The Workflow module runs server-driven multi-step workflows where step ordering and configuration come from the backend per session. Unlike the dashboard-defined Flow, a Workflow lets the server emit nodes dynamically — including custom-module nodes that callbacks back into your code.
Follows the composite / orchestrator pattern, with an additional
asyncResolutionstate for server-side processing nodes. See the patterns page for the shared lifecycle.
Tag
<incode-workflow> is a standard Web Component. Importing the UI subpath registers the custom element; importing the CSS applies the module's styles.
import '@incodetech/web/workflow';
import '@incodetech/web/workflow/styles.css';Properties
| Property | Type | Required | Description |
|---|---|---|---|
config | WorkflowConfig | ❌ | Workflow configuration (server-driven) |
onFinish | () => void | ❌ | Called when the workflow completes |
onError | (error: string) => void | ❌ | Called when an error occurs |
Configuration
WorkflowConfig is fetched from the backend via GET /omni/workflow/info:
type WorkflowConfig = {
id: string;
name: string;
redirectDesktopToMobile: boolean;
disableSmsOption?: boolean;
addContinueToDesktop?: boolean;
qrPhishingResistance?: boolean;
disableUnsupportedBrowserScreen?: boolean;
oauth2Secured?: boolean;
ds?: boolean; // Deepsight enabled
mergeSessionRecordings?: boolean;
ageAssurance?: boolean;
disableLaunchScreen?: boolean;
};The shape is largely informational — the workflow nodes themselves drive what runs. The boolean flags propagate to sub-modules (e.g., mergeSessionRecordings and ageAssurance to ID Capture; ds to Selfie).
disableLaunchScreen controls the SDK's built-in launch / home screen. When the backend sets it to true, the SDK skips the launch screen and goes straight to the first workflow node. When false (or omitted), the workflow surfaces a homeScreen.visible === true state — the consumer must render the launch screen and call continueFromHome() on user confirmation.
State machine
WorkflowState is a discriminated union over status. idle, loading, and ready additionally carry a homeScreen: { visible: boolean; isContinueLoading: boolean } property — see Launch screen below.
| Status | Description | Properties |
|---|---|---|
idle | Initial state before load() | homeScreen |
loading | Fetching the next node from the workflow server | homeScreen |
ready | Current WorkflowNode is active. Render the corresponding sub-module. | workflowConfig, currentNode, config, moduleState, homeScreen |
asyncResolution | Server is processing async; UI shows progress until the next node arrives. | workflowConfig, currentNode |
finished | Terminal — workflow's last node was a FINISH node. | workflowConfig, finishStatus |
closed | User dismissed | – |
error | Fatal error | error, errorCode? |
Launch screen
When the backend does not set WorkflowConfig.disableLaunchScreen, the workflow exposes a launch / home screen overlay before running the first node. The overlay is signalled via state.homeScreen.visible:
- Render your launch screen when
homeScreen.visible === true. - Call
manager.continueFromHome()on user confirmation;homeScreen.isContinueLoadingbecomestruewhile the orchestrator finishes loading the first module. - When
disableLaunchScreenistrue, the SDK never setshomeScreen.visibleand you can skip rendering the overlay entirely.
Each WorkflowNode carries:
type WorkflowNode = {
id: string;
nodeType: 'MODULE' | 'FINISH' | 'ASYNC_RESOLUTION';
moduleKey: string; // e.g., 'PHONE', 'SELFIE', 'CUSTOM_MODULE'
moduleConfiguration: Record<string, unknown>;
status: string;
workflowId: string;
};API methods
| Method | Description |
|---|---|
load() | Start loading the workflow configuration and the first node from the backend. Call once. |
completeModule() | Mark the current module as complete. Call from the active module's onFinish callback to advance to the next node. |
errorModule(error) | Mark the current module as failed and transition the workflow to a terminal error state. |
completeFlow() | Skip remaining nodes and go straight to the completion step. Used when the workflow was completed externally — e.g. via the desktop → mobile redirect handoff. |
continueFromHome() | Advance past the SDK's launch / home screen. Only meaningful when state.homeScreen.visible === true; no-op otherwise (e.g. when disableLaunchScreen is true). |
getModuleConfig<T>() | Returns the current node's moduleConfiguration merged with workflow-level flags (ds). Typed via the generic parameter. |
getState() | Get the current workflow state synchronously. |
subscribe(callback) | Subscribe to workflow state changes (returns an unsubscribe function). |
Plus the universal manager lifecycle: reset, stop.
Custom module callback
Workflows can include CUSTOM_MODULE nodes that hand control back to your code. Wire a CustomModuleCallback to handle them — it receives interviewId, nodeId, and the configured name, plus onSuccess / onError hooks that advance the workflow.
import { createWorkflowManager } from '@incodetech/core/workflow';
const manager = createWorkflowManager({
config: { /* WorkflowConfig fetched server-side */ },
customModuleCallback: ({ interviewId, nodeId, name, onSuccess, onError }) => {
// Run your custom logic here, then call one of:
onSuccess('Custom check passed');
// or onError('Something went wrong');
},
});See also
- IncodeFlow Component: the dashboard-driven flow alternative
- Module Patterns → composite
- Headless Mode → Orchestrated Flow Manager
- Individual Modules
Updated 1 day ago
