Framework Integration
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.
Every Incode UI module ships as a standard Web Component — registered via a side-effect import (import '@incodetech/web/<module>') and consumed like any HTML element. Because the elements are framework-agnostic, the same SDK code runs from vanilla HTML, React, Angular, Vue, or any other web framework. The only difference is how each framework lets you mount custom elements and bind non-string properties.
This page documents the four mainstream paths. All of them share one rule:
Set
config,onFinish, andonErroras JavaScript properties on the element, not as HTML attributes. They are object/function values, not strings, so they can't go throughsetAttribute. Each framework section below shows how to do that idiomatically.
Vanilla HTML / TypeScript
<incode-flow id="flow"></incode-flow>
<script type="module">
import { setup } from '@incodetech/core';
import '@incodetech/web/flow';
import '@incodetech/web/flow/styles.css';
await setup({ apiURL: 'https://demo-api.incodesmile.com', token: session.token });
const flow = document.getElementById('flow');
flow.config = { token: session.token };
flow.onFinish = (result) => {
/* ... */
};
</script>The same shape applies to every other module — replace flow with phone, selfie, id, etc., and set the corresponding config / handlers on the element.
React
Universal pattern (works on React 16.8+)
Use the custom element directly with a ref. React renders custom elements as-is, and you assign non-string properties imperatively in useEffect. This works on every React version since hooks landed:
import { useEffect, useRef } from 'react';
import { setup } from '@incodetech/core';
import type { FlowConfig } from '@incodetech/web/flow';
import type { FinishStatus } from '@incodetech/core/flow';
import '@incodetech/web/flow';
import '@incodetech/web/flow/styles.css';
type FlowElement = HTMLElement & {
config: FlowConfig;
onFinish: (result?: FinishStatus) => void;
};
export function MyFlow({ token }: { token: string }) {
const ref = useRef<FlowElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
el.config = { token };
el.onFinish = (result) => console.log('Done:', result);
}, [token]);
return <incode-flow ref={ref} style={{ display: 'block', height: '100vh' }} />;
}React 19+ shortcut
React 19 ships native custom-element support: it sets non-string JSX props as DOM properties and bridges on* props through addEventListener. If you're on React 19 you can drop the ref + useEffect ceremony entirely:
import { setup } from '@incodetech/core';
import '@incodetech/web/flow';
import '@incodetech/web/flow/styles.css';
export function MyFlow({ token }: { token: string }) {
return (
<incode-flow
config={{ token }}
onFinish={(result) => console.log('Done:', result)}
onError={(error, code) => console.error(error, code)}
style={{ display: 'block', height: '100vh' }}
/>
);
}This shortcut does not work on React 18 or earlier — those versions serialize JSX props through setAttribute, which coerces config={{token}} to the string "[object Object]". Use the universal pattern above unless you're certain every consumer of your code is on React 19+.
TypeScript: JSX support for incode-* tags
incode-* tagsReact 19+ treats unknown lowercase tags as HTML elements automatically — no extra TypeScript setup is needed.
React 18 and earlier strict-checks JSX.IntrinsicElements, so referencing <incode-flow> (or any other Incode tag) directly in JSX errors out. Add a one-time augmentation somewhere in your project (e.g. src/types/incode.d.ts) that covers every incode-* tag your app uses:
// src/types/incode.d.ts
import 'react';
type IncodeElementAttrs = React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>;
declare global {
namespace JSX {
interface IntrinsicElements {
'incode-flow': IncodeElementAttrs;
'incode-flow-completed': IncodeElementAttrs;
'incode-selfie': IncodeElementAttrs;
'incode-id': IncodeElementAttrs;
'incode-phone': IncodeElementAttrs;
'incode-email': IncodeElementAttrs;
'incode-document-capture': IncodeElementAttrs;
'incode-face-match': IncodeElementAttrs;
'incode-consent': IncodeElementAttrs;
'incode-geolocation': IncodeElementAttrs;
'incode-antifraud': IncodeElementAttrs;
'incode-curp-validation': IncodeElementAttrs;
'incode-identity-reuse': IncodeElementAttrs;
'incode-redirect-to-mobile': IncodeElementAttrs;
'incode-signature': IncodeElementAttrs;
'incode-electronic-signature': IncodeElementAttrs;
'incode-ae-signature': IncodeElementAttrs;
'incode-qe-signature': IncodeElementAttrs;
'incode-ekyc': IncodeElementAttrs;
'incode-ekyb': IncodeElementAttrs;
'incode-workflow': IncodeElementAttrs;
'incode-cross-document-data-match': IncodeElementAttrs;
// Add any other incode-* tags you mount; the shape is identical.
}
}
}The element-specific properties (config, onFinish, onError) are set imperatively through the ref — that's why IncodeElementAttrs is just the standard HTML element shape. The full per-tag catalog lives in Web Components.
Angular
Add CUSTOM_ELEMENTS_SCHEMA to the module that uses Incode tags:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
declarations: [MyFlowComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}Then bind to the element's properties from a template using property binding:
<incode-flow [config]="flowConfig" (onFinish)="handleFinish($event)"></incode-flow>Vue 3
Tell the template compiler to treat incode-* tags as custom elements:
// vite.config.ts
import vue from '@vitejs/plugin-vue';
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('incode-'),
},
},
});Then bind properties with .prop modifiers:
<incode-flow :config.prop="flowConfig" :onFinish.prop="handleFinish" />See also
- Getting Started: three integration paths walked through end to end
- IncodeFlow Component: the all-in-one component reference
- Web Components: full tag catalog
- Individual Modules: per-module reference pages
- Troubleshooting → Build / TypeScript issues: common JSX errors and fixes
Updated 1 day ago
