# Web Components

<WebSDK2 />

All SDK consumer components ship as standard Web Components, enabling framework-agnostic integration. For the complete catalog see [Individual Modules](doc: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`                        |

## Usage

Import the module's UI subpath to register the custom element (a side-effect import), then use it in 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
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
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
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](doc: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
:root {
  --button-primary-surface-default: #0066cc;
  --text-title: #333333;
}
```

See [Theming & Styling](doc: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
<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.

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

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

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

```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);
}
```

## See Also

* [Getting Started](doc:web-sdk-2-getting-started): three integration paths walked end-to-end
* [IncodeFlow Component](doc:web-sdk-2-incodeflow-component): full `<incode-flow>` reference
* [Individual Modules](doc:web-sdk-2-individual-modules): every module the SDK ships
