## Web SDK Installation
Review these pages before starting:

- [Getting Started with Incode Web SDK](https://developer.incode.com/docs/web-sdk-integrations)
- [Create a new Onboarding Session using the Omni API](https://developer.incode.com/docs/single-onboarding)

Next, use the following code to integrate the [current version](https://developer.incode.com/docs/releases-web-sdk) of the Incode Web SDK into your web application.

### CDN (script tag)
```html
  <!-- Include Incode Web SDK inside the head tag -->
  <script src="https://sdk.incode.com/sdk/onBoarding-1.83.0.js" defer></script>
```

### NPM Package
```text
npm install @incodetech/welcome
```

## Sample Code
You can find sample code for this approach in [Code Samples for Web Integrations](https://developer.incode.com/docs/code-samples-for-web-integrations). This includes a `fake_backend.js` with all the needed steps to move to a formal back end for production.

## Steps
This tutorial uses a linear approach; that is, all Incode verification modules are executed one after the other. The following diagram illustrates this at a high level:

This approach is the most convenient for scenarios where you want users to go through all the Incode modules before they go any further in your application.

## Set up tutorial project
Set up a project with the following structure:

### Vanilla Structure
```javascript
my-incode-app
|__ index.html
|__ app.js
```

### NPM Package Structure
```javascript
my-incode-app
 |__index.html
 |__main.js
 |__package.json
 |__.env
```

## Set up HTML
Some SDK methods require an HTML element to contain the UI components. A `div` element with the id `incode-container` will hold the SDK components as shown in the following code. https://demo-api.incodesmile.com/0/

### index.html

### Vanilla Structure
```html
<!DOCTYPE html>
<html lang="en" translate="no">
<head>
  <title>Incode WebSdk</title>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="google" content="notranslate">
  <script src="https://sdk.incode.com/sdk/onBoarding-1.83.0.js" defer></script>
  <script src="./app.js" defer></script>
</head>
<body>
  <div id="incode-container"></div>
</body>
</html>
```

### NPM Package Structure
```html
<!DOCTYPE html>
<html lang="en" translate="no">
<head>
  <title>Incode WebSdk</title>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="google" content="notranslate">
</head>
<body>
	<div id="incode-container"> </div>
	<script type="module" src="/main.js"></script>
</body>
</html>
```

### Known Issue: DOM mutations by Google Translate
Observe the `translate="no"` attribute at the `html` tag and the `<meta name="google" content="notranslate">` within the `head` tag. You should include them in your project to prevent undesired DOM mutations from Google Chrome's Translate functionality. These mutations may cause DOM errors in your integration.

If your application requires multiple languages, read our guide on how to include and customize [String Localizations](https://developer.incode.com/docs/localization-and-strings).

## Initialize the Web SDK
1. Initialize the Incode Web SDK using the `create` method.
2. Create a new Onboarding Session.
3. Create a reference to the HTML element that will contain the SDK UI components.

### app.js

### Vanilla Structure
```javascript
let incode;
async function app(){
  incode = await window.OnBoarding.create({
    apiURL: "https://demo-api.incodesmile.com/0/" // API URL provided by Incode
  });
  await incode.initialize();
}

document.addEventListener("DOMContentLoaded", app);
```

### NPM Package Structure
```javascript
import { create } from '@incodetech/welcome';

let incode;
async function app() {
  incode = create({
    apiURL:"https://demo-api.incodesmile.com/0/" // API URL provided by Incode
  });
  await incode.initialize();
}

document.addEventListener("DOMContentLoaded", app);
```

## Fetch a `session` object
### Create a `session` object
An Onboarding Session Token (or just "session token") is required. It provides a link between all the user information and the validation results.

> 📘  
> **NOTE**  
> If you don't know how to create an onboarding session, read the guide on [creating onboarding sessions](https://developer.incode.com/docs/single-onboarding) from your application back end before you continue.

### Save the session token for later
If you already know how to create an onboarding session, you can fetch a new session object from your application back end and save the response in a variable (`session`) for later use. The following code shows how to do this.

### Vanilla Structure
```javascript
let incode;
let session;
async function app(){
  incode = await window.OnBoarding.create({
    apiURL: "https://demo-api.incodesmile.com/0/" // API URL provided by Incode
  });
  await incode.initialize();
  // Get the session from your backend
  session = await mySessionRequestMethod();
}

document.addEventListener("DOMContentLoaded", app);
```

### NPM Package Structure
```javascript
import { create } from '@incodetech/welcome';

let incode;
let incodeSession;
async function app() {
  incode = create({
    apiURL: "https://demo-api.incodesmile.com/0/" // API URL provided by Incode
  });
  await incode.initialize();
  // Get the session from the backend
  incodeSession = await mySessionRequestMethod();
}

document.addEventListener("DOMContentLoaded", app);
```

### Use the onboarding `session` object
The `session` object contains two properties:

```json
{
  "token": "abc123",
  "interviewId": "xyz098"
}
```

- `token`: Session token that is sent in every call to the Incode API
- `interviewId`: Unique identifier of the current Incode onboarding session

In almost all cases, you need the full `session` object value as an input parameter for the SDK methods. However, specific methods may only require the `token` value. Read our official SDK Methods reference to know when to use each.

The next steps in building your app involve the Incode onboarding Modules. These Modules are discussed in the recommended implementation order, as shown in the image at the top of this page.

## One - Check for any applicable mandatory Biometric Consent
Laws around biometric consent can change from country to country and even from state to state. These laws apply to you depending on where the user is from and where the customer is accessing your system—even if they are using a VPN. You might be subject to fines and penalties even if you didn't know you had to get proper consent from the user.

This pattern of integration lets you leverage the Incode system to detect whether the end user's location is subject to such regulations. Further verifications are done once we know the user's geolocation via GPS and again when we analyze their ID card to determine their origin.

The Biometric Consent check returns a boolean result in our `sendFingerprint()` method. It clearly shows if biometric consent is necessary and provides any relevant `regulationType` for such consent.

You can then show the relevant biometric consent using `renderBiometricConsent()`.

In most cases your end user will never see this consent. However, this is likely to change as privacy laws become stricter.

### app.js
```javascript
const incodeContainer = document.querySelector("#incode-container");
// 1.- Check if mandatory consent is required. and show it if it is.
function checkMandatoryConsent() {
  incode.sendFingerprint({ token: incodeSession.token }).then((response) => {
    // Send fingerprint returns a response with the following structure:
    //   {
    //     "success": true,
    //     "sessionStatus": "Alive",
    //     "ipCountry": "UNITED STATES",
    //     "ipState": "ILLINOIS",
    //     "showMandatoryConsent": true,
    //     "regulationType": "US_Illinois"
    // }
    // If the response has showMandatoryConsent and is set to true, we need to show the mandatory consent
    if (response?.showMandatoryConsent) {
      incode.renderBiometricConsent(incodeContainer, {
        token: incodeSession,
        onSuccess: captureCombinedConsent,
        onCancel: () => showError("Mandatory consent was denied"),
        regulationType: response.regulationType,
      });
    } else {
      captureCombinedConsent();
    }
  });
}
```

## Two - Show Data Sharing Consent
Before you get any more information from the end user, you must need ask for their consent, Our [Data Sharing Consent (or combinedConsent) Module](https://developer.incode.com/docs/combined-consent) makes this easy.

If you haven't already done so, you can create your first consent and get the `consentId` for this function from **Dashboard > Configuration > Consents**.

### app.js
```javascript
// 2.- Show the combined consent
//    This consent is created in the dashboard and has to be passed as a parameter
//    to the renderCombinedConsent function.
function captureCombinedConsent() {
  incode.renderCombinedConsent(incodeContainer, {
    token: incodeSession,
    onSuccess: sendGeolocation,
    consentId: consentId, // id of a consent created in dashboard
  });
}
```

## Three - Capture Geolocation
Create the following function in your `app.js` to capture the geolocation of the user.

### app.js
```javascript
// 3.- Send geolocation and start the ID capture flow
function sendGeolocation() {
  incode.sendGeolocation({ token: incodeSession.token });
  captureId();
}
```

## Four - Capture and validate ID card
There are two steps to validate an ID card. First, capture the front and back sides of the ID using the `renderCaptureId()` method. Second, execute the ID validation process (covered in the following section Five).

The `renderCaptureId()` method is a ready-to-use component. It can activate the device camera and present a capture assistant to capture the ID.

### app.js
```javascript
// 4.- Capture the ID
function captureId() {
  incode.renderCaptureId(incodeContainer, {
    session: incodeSession,
    onSuccess: processId,
    onError: showError,
    forceIdV2: false //default to false
  });
}
```

## Five - Process ID
Identity validations and OCR data extraction occur on the Incode platform. This processing is triggered using the `processId()` method.

### app.js
```javascript
// 5.- Process the ID
async function processId() {
  return incode.processId({ token: incodeSession.token })
    .then(() => {
      captureSelfie();
    })
    .catch((error) => {
      showError(error);
    });
}
```

## Six - Validate user selfie against ID
To compare the face of the user against the photo in the ID, use the `renderCaptureFace()` method one more time.

### app.js
```javascript
// 6.- Capture the selfie
function captureSelfie() {
  incode.renderCaptureFace(incodeContainer, {
    session: incodeSession,
    onSuccess: processFace,
    onError: showError,
    forceV2: false //default to false
  });
}
```

## Seven - Process face
Face validations and OCR data extraction occur on the Incode platform. This processing is triggered using the `processFace()` method.

### app.js
```javascript
// 7.- Process the Face
async function processFace() {
  return incode.processFace({ token: incodeSession.token })
    .then(() => {
      finishOnboarding();
    })
    .catch((error) => {
      showError(error);
    });
}
```

## Eight - Mark the onboarding session as complete
Marking an onboarding session as complete tells the Incode platform that the user has finished all flow steps, regardless of the scores.

### app.js
```javascript
async function app() {
  incode = create({
    apiURL: "https://demo-api.incodesmile.com/0/" // API URL provided by Incode
  });
  // Get the session from the backend
  incodeSession = await mySessionRequestMethod();
  // Run first step in the validation
  checkMandatoryConsent();
}
```

## Test your app
Your application should be fully functional at this point. You should test it thoroughly before putting it into production. Here are some recommendations for making it available for testing:
- All HTTP requests executed from the Web SDK are secured. Run your application over HTTPS. Otherwise, it may cause mixed content warnings and CORS errors.
- The Incode Web SDK is compatible with most development environments and frameworks like Express and Vite. You can use a local server or make it public so others can test it.
