# Web SDK 2.0 Guide

This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](https://developer.incode.com/docs/web-sdk-reference). Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade.

Full rollout to all clients still TBD.

All SDK consumer components ship as standard Web Components, enabling framework-agnostic integration. For the complete catalog see [Individual Modules](https://developer.incode.com/docs/web-sdk-2-individual-modules); the table below is the most-used subset.

## Available Components

| Tag name | Description | Side-effect import |
| --- | --- | --- |
| `<incode-flow>` | Complete orchestrated flow | `@incodetech/web/flow` |
| `<incode-flow-completed>` | Optional post-flow completion screen with auto-redirect | `@incodetech/web/flow` (auto-registered alongside `<incode-flow>`) |
| `<incode-id>` | ID document capture | `@incodetech/web/id` |
| `<incode-selfie>` | Selfie capture | `@incodetech/web/selfie` |
| `<incode-phone>` | Phone verification | `@incodetech/web/phone` |
| `<incode-email>` | Email verification | `@incodetech/web/email` |
| `<incode-document-capture>` | Generic document capture | `@incodetech/web/document-capture` |
| `<incode-face-match>` | Selfie ↔ ID face match | `@incodetech/web/face-match` |
| `<incode-consent>` | Consent capture | `@incodetech/web/consent` |
| `<incode-geolocation>` | Geolocation capture | `@incodetech/web/geolocation` |
| `<incode-antifraud>` | Antifraud signals | `@incodetech/web/antifraud` |
| `<incode-curp-validation>` | CURP validation (Mexico) | `@incodetech/web/curp-validation` |
| `<incode-identity-reuse>` | Identity reuse | `@incodetech/web/identity-reuse` |
| `<incode-redirect-to-mobile>` | Desktop → mobile handoff | `@incodetech/web/redirect-to-mobile` |
| `<incode-signature>` | Handwritten signature | `@incodetech/web/signature` |
| `<incode-electronic-signature>` | Electronic signature | `@incodetech/web/electronic-signature` |
| `<incode-ae-signature>` | Advanced Electronic Signature | `@incodetech/web/ae-signature` |
| `<incode-qe-signature>` | Qualified Electronic Signature | `@incodetech/web/qe-signature` |
| `<incode-ekyc>` | KYC composite | `@incodetech/web/ekyc` |
| `<incode-ekyb>` | KYB composite | `@incodetech/web/ekyb` |
| `<incode-workflow>` | Server-driven multi-step workflow | `@incodetech/web/workflow` |
| `<incode-cross-document-data-match>` | Multi-document cross-check | `@incodetech/web/cross-document-data-match` |
| `<incode-certificate-issuance>` | Verifiable certificate issuance | `@incodetech/web/certificate-issuance` |
| `<incode-field-comparison>` | Cross-source field comparison | `@incodetech/web/field-comparison` |
| `<incode-government-validation>` | Government registry validation | `@incodetech/web/government-validation` |
| `<incode-fiscal-qr>` | Mexican Fiscal QR scan | `@incodetech/web/fiscal-qr` |
| `<incode-video-selfie>` | Recorded multi-step video selfie | `@incodetech/web/video-selfie` |

## Usage

Import the module's UI subpath to register the custom element (a side-effect import), then use it in HTML:

### HTML

```html
<incode-flow id="flow"></incode-flow>

<script type="module">
  import { setup } from '@incodetech/core';
  import { createSession } from '@incodetech/core/session';
  import '@incodetech/web/themes/light.css';
  import '@incodetech/web/base.css';
  import '@incodetech/web/flow';
  import '@incodetech/web/flow/styles.css';

// Create session (move to backend for production)
  await setup({ apiURL: 'https://demo-api.incodesmile.com', token: '' });
  const session = await createSession('your-api-key', {
    configurationId: 'your-config-id',
  });
  await setup({
    apiURL: 'https://demo-api.incodesmile.com',
    token: session.token,
  });

const flow = document.getElementById('flow');
  flow.config = {
    token: session.token, // ← the FlowConfig accepts `token`, not `apiURL`
    lang: 'en-US',
    enableHome: true,
  };
  flow.onFinish = (result) => console.log(result);
</script>
```

> **Note:** `apiURL` belongs on the global `setup()` call, _not_ inside the `<incode-flow>` component config. The component's `config` accepts `token` (or `apiKey` + `configurationId` for self-loading), plus optional flags like `lang`, `enableHome`, `authHint`, `wasmConfig`, `spinnerConfig`, and event callbacks (`onFlowEvent`, `onModuleLoading`, etc.).

## Setting Properties

Properties can be set via JavaScript:

### JavaScript

```javascript
const element = document.querySelector('incode-phone');

// Object properties (config)
element.config = {
  otpVerification: true,
  otpExpirationInMinutes: 5,
  prefill: false,
};

// Callback properties
element.onFinish = () => console.log('Done!');
element.onError = (err) => console.error(err);
```

## TypeScript Support

The SDK provides full TypeScript support for Web Components via `HTMLElementTagNameMap` augmentation. When you import from `@incodetech/web`, DOM APIs automatically return correctly typed elements:

### TypeScript

```typescript
import '@incodetech/web/flow';

// Automatically typed - no cast needed!
const flow = document.createElement('incode-flow');
flow.config = {
  token: 'session-token',
  lang: 'en-US',
};
flow.onFinish = (result) => {
  // ✅ result is typed
  console.log(result.action); // 'approved' | 'rejected' | 'none'
};
```

For module components:

### TypeScript

```typescript
import '@incodetech/web/phone';

const phone = document.createElement('incode-phone');
phone.config = {
  otpVerification: true,
  otpExpirationInMinutes: 5,
  prefill: false,
};
phone.onFinish = () => console.log('Verified!');
phone.onError = (error) => console.error(error);
```

See [TypeScript Types](https://developer.incode.com/docs/web-sdk-2-typescript-types#web-component-element-types) for the full list of available element types.

## Styling

Web Components inherit CSS variables from your page:

### CSS

```css
:root {
  --button-primary-surface-default: #0066cc;
  --text-title: #333333;
}
```

See [Theming & Styling](https://developer.incode.com/docs/web-sdk-2-theming) for all available variables.

## Framework Integration

### Vue

`onFinish`/`onError` are properties (not DOM events), so use `.prop` binding to set them — the regular `@event` syntax binds to events, not properties.

### Vue Example

```vue
<template>
  <incode-flow ref="flowEl" />
</template>

<script setup>
import '@incodetech/web/themes/light.css';
import '@incodetech/web/base.css';
import '@incodetech/web/flow';
import '@incodetech/web/flow/styles.css';
import { ref, onMounted } from 'vue';
import { setup } from '@incodetech/core';
import { createSession } from '@incodetech/core/session';

const flowEl = ref(null);

onMounted(async () => {
  await setup({ apiURL: 'https://demo-api.incodesmile.com', token: '' });
  const session = await createSession('your-api-key', {
    configurationId: 'your-config-id',
  });
  await setup({
    apiURL: 'https://demo-api.incodesmile.com',
    token: session.token,
  });

flowEl.value.config = { token: session.token, lang: 'en-US' };
  flowEl.value.onFinish = (result) => console.log('Done!', result);
  flowEl.value.onError = (error) => console.error(error);
});
</script>
```

### Angular

`onFinish` / `onError` are properties on the element, so use property binding (`[onFinish]="..."`) — `(eventName)` binds DOM events, which the SDK does not dispatch.

#### Angular Example

```typescript
// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@incodetech/web/flow';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
```

### HTML

```html
<incode-flow #flow [config]="flowConfig"></incode-flow>
```

### TypeScript

```typescript
// component.ts
@ViewChild('flow', { static: true }) flow!: ElementRef<HTMLElement>;

ngAfterViewInit() {
  (this.flow.nativeElement as any).onFinish = (result: any) => this.handleFinish(result);
  (this.flow.nativeElement as any).onError = (error: any) => this.handleError(error);
}
```
