Overview
The Form module provides a complete pre-built eKYC form UI that guides users through the identity verification process. It handles the full flow from welcome screen through document selection, data entry, review, submission, and results - all with a single component.
The form module supports three configuration types:
- OCR - Document capture with automatic data extraction
- Manual - Manual data entry by the user
- Doc Upload - Document file upload for verification
Accessing the Module
The Form module is accessed through the SDK’s component factory using the React provider:
const sdk = await OneSdk({
mode: 'production',
session: { token: 'your-token' }
});
const formComponent = sdk.component('form', {
name: 'WELCOME',
mode: 'individual',
type: 'manual'
});
Configuration
Module Options
Options are passed during module initialization:
| Option | Type | Required | Description |
|---|
name | ReactFormIdsKeys | Yes | The screen to start on. See Screens. |
mode | 'individual' | No | Verification mode. Defaults to 'individual' for personal KYC. |
type | 'ocr' | 'manual' | 'doc_upload' | No | Configuration type. Determines the verification flow pattern. Primarily affects the Document Selection, Personal Details, Review, and Retry screens. Static screens (Welcome, Consent, Start) and progress screens (Loading, Result) are not affected. Doc upload screens are only shown when type is 'doc_upload'. |
The module options also accept page-level configuration overrides. See Configuration for all available customization options.
Recipe Configuration
The Form module requires provider configuration in your recipe. Form configuration (screens, type, styling) is set through module options when calling sdk.component('form', options), not in the recipe.
const sdk = await OneSdk({
session: { token: 'your-token' },
recipe: {
form: {
provider: {
name: 'react',
googleApiKey: 'your-google-api-key',
useGoogleAutoCompleteSuggestion: true
}
}
}
});
Recipe Options
| Property | Type | Required | Description |
|---|
provider.name | 'react' | Yes | Must be 'react' for the React form provider. |
provider.googleApiKey | string | No | Google API key with the Places API enabled. Enables address autocomplete on address field types. Google Maps is optional — when no key is provided, users enter their address manually. Load the Google Maps JS API (<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places"></script>) before initializing OneSdk. |
provider.useGoogleAutoCompleteSuggestion | boolean | No | Default: false. When true, uses the newer AutocompleteSuggestion API instead of the deprecated AutocompleteService. As of March 1, 2025, Google deprecated AutocompleteService for new customers — set this to true for new integrations. |
docUpload | object | No | Document upload configuration. See Document Upload Configuration. |
Methods
mount()
Mounts the Form component to a DOM element.
Signature:
mount(mountElement: string | HTMLElement): Promise<WrapperContext>
Parameters:
| Parameter | Type | Required | Description |
|---|
mountElement | string | HTMLElement | Yes | CSS selector string (e.g., '#form-container') or HTMLElement object where the form will be mounted |
Returns: Promise<WrapperContext> - Resolves when the form is mounted. The WrapperContext contains a cleanup() method.
Example:
// Mount to element by ID
await formComponent.mount('#form-container');
// Mount to element reference
const container = document.getElementById('form-container');
await formComponent.mount(container);
unmount()
Unmounts the Form component from the DOM.
Signature:
Example:
provider
Read-only property indicating the current vendor.
Type: 'react'
console.log(formComponent.provider); // 'react'
Events
The Form module uses a structured event system with two levels:
Global Events
These events apply to the form module as a whole:
| Event | Parameters | Description |
|---|
ready | { domElement, config } | Form component is ready. Contains the mount element and resolved configuration. |
loaded | { domElement, provider } | Form component is loaded and rendered. |
results | { documents, applicant, entityId } | Verification results received. Contains the submitted documents, applicant data, and entity ID. |
navigation | { page } | User navigated to a different screen. Contains the screen name. |
destroy | (none) | Form component is being destroyed/unmounted. |
Example:
formComponent.on('ready', ({ domElement, config }) => {
console.log('Form ready with config:', config);
});
formComponent.on('results', ({ documents, applicant, entityId }) => {
console.log('Verification complete for:', entityId);
console.log('Documents:', documents);
console.log('Applicant:', applicant);
});
formComponent.on('navigation', ({ page }) => {
console.log('User navigated to:', page);
});
Screen Events
Each screen emits events following the pattern form:{screen}:{stage}. See Screens for the complete screen event reference.
Event Pattern:
form:welcome:ready
form:welcome:loaded
form:welcome:failed
form:consent:ready
form:review:success
form:result:pending
...
Event Stages:
| Stage | Description |
|---|
ready | Screen is ready to be displayed |
loaded | Screen has been rendered |
failed | Screen failed to load |
success | Screen action completed successfully (review, result, doc_upload only) |
partial | Partial verification result (review, result only) |
pending | Verification pending (review, result only) |
back | User navigated back (document only) |
navigate | User navigated to another screen (document, doc_upload only) |
form:review:* events require customResult: trueThe form:review:success, form:review:failed, form:review:partial, and form:review:pending events are only emitted when customResult: true is set in manual mode. When customResult is false (the default), the form automatically navigates to and displays the configured result screen without emitting these events.In OCR mode, the only terminal event is ready on the final screen.
Event Payload:
All screen events emit an EventPayload:
{
componentName?: string; // Module name
provider?: string; // Provider name ('react')
inputInfo: {
name?: string; // Screen name (e.g., 'welcome', 'review')
type?: string; // Config type ('ocr', 'manual', 'doc_upload')
documentType?: string; // Document type if applicable
index?: number; // Document index if applicable
}
}
Complete Example
import OneSdk from '@frankieone/one-sdk';
async function startVerificationForm() {
// Initialize SDK
const sdk = await OneSdk({
mode: 'production',
session: { token: await getSessionToken() },
recipe: {
form: {
provider: {
name: 'react',
googleApiKey: 'your-google-api-key',
useGoogleAutoCompleteSuggestion: true
}
}
}
});
// Create form component
const formComponent = sdk.component('form', {
name: 'WELCOME',
mode: 'individual',
type: 'manual'
});
// Global events
formComponent.on('ready', ({ domElement, config }) => {
console.log('Form ready');
});
formComponent.on('loaded', ({ domElement, provider }) => {
console.log('Form loaded with provider:', provider);
});
// Track navigation
formComponent.on('navigation', ({ page }) => {
console.log('Current screen:', page);
updateProgressBar(page);
});
// Screen-level events
formComponent.on('form:welcome:loaded', (payload) => {
console.log('Welcome screen displayed');
});
formComponent.on('form:consent:loaded', (payload) => {
console.log('Consent screen displayed');
});
formComponent.on('form:document:loaded', (payload) => {
console.log('Document selection displayed');
});
formComponent.on('form:review:ready', (payload) => {
console.log('Review screen ready');
});
formComponent.on('form:review:success', (payload) => {
console.log('Review submitted successfully');
});
formComponent.on('form:review:partial', (payload) => {
console.log('Partial match - additional verification needed');
});
formComponent.on('form:result:success', (payload) => {
console.log('Verification passed');
});
formComponent.on('form:result:pending', (payload) => {
console.log('Verification pending review');
});
// Final results
formComponent.on('results', ({ documents, applicant, entityId }) => {
console.log('Verification complete');
console.log('Entity:', entityId);
handleVerificationResult({ documents, applicant, entityId });
});
// Mount the form
await formComponent.mount('#form-container');
}
Best Practices
-
Set up event listeners before mounting - Register all event handlers before calling
mount() to avoid missing early events like ready and loaded.
-
Handle all verification outcomes - Listen for
success, partial, and pending on both form:review and form:result screens. Don’t assume verification always results in a clear pass/fail.
-
Use the
navigation event for progress tracking - The global navigation event fires on every screen change, making it ideal for progress bars, analytics, and conditional UI outside the form.
-
Configure
type to match your flow - Choose 'ocr', 'manual', or 'doc_upload' based on your integration. The type determines which screens are shown and how data is collected. See Configuration Types.
-
Customize screens via page config, not DOM manipulation - Use the page configuration and CSS class keys to customize appearance and content rather than manipulating the DOM directly.
Common Issues
Component not displaying
Ensure the mount element exists in the DOM before calling mount() and has sufficient size:
#form-container {
width: 100%;
min-height: 600px;
}
Google address autocomplete not working
Ensure googleApiKey is set in the recipe and the Google Places API is enabled for the key. If using useGoogleAutoCompleteSuggestion, the API key must have the Places API (New) library enabled.
The fields shown on the Review and Personal Details screens depend on the type option and the document type selected. Ensure your form field configuration and country-specific settings match the document types available in your flow.
Sub-Pages