Skip to content

Angular v15

decebal edited this page Apr 22, 2026 · 4 revisions

Integrating with an Angular 15 project using the traditional NgModule-based architecture.

For Angular 19 (standalone components, zoneless), see the Angular v19 guide.

The example code below was initially generated with the Angular CLI and utilises Angular services to fetch tokens and use the Support Checker.

Zone.js Configuration

The iProov Web SDK performs native API integrity checks at initialisation. Zone.js patches EventTarget by default, which can interfere with these checks. To prevent this, create a zone-flags.js file and load it before zone.js in your angular.json scripts array:

zone-flags.js

window.__Zone_disable_EventTarget = true

angular.json (partial)

"scripts": [
  "src/zone-flags.js"
]

Module Setup

app.module.ts

import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core"
import { BrowserModule } from "@angular/platform-browser"
import { HttpClientModule } from "@angular/common/http"

import { AppComponent } from "./app.component"
import { IproovComponent } from "./iproov/iproov.component"

@NgModule({
  declarations: [AppComponent, IproovComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

CUSTOM_ELEMENTS_SCHEMA is required so Angular allows the <iproov-me> web component in templates.

app.component.ts

import { Component } from "@angular/core"

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
})
export class AppComponent {
  title = "iProov Web SDK Angular Example"
}

app.component.html

<div class="content" role="main">
  <h2>iProov Angular Example</h2>
  <!-- iproov-me is injected by the component after token generation -->
  <iproov-component></iproov-component>
</div>

iProov Component

iproov.component.ts

import { Component, Input } from "@angular/core"
import "@iproov/web-sdk"
import { iProovSupport, iProovSupportCheck } from "@iproov/web-sdk/iProovSupport.js"
import { IproovTokenService } from "./iproov-token.service"
import { IproovSupportCheckerService } from "./iproov-support-checker-service"

@Component({
  selector: "iproov-component",
  templateUrl: "./iproov.component.html",
})
export class IproovComponent {
  @Input() token: string = ""
  @Input() base_url: string = "***YOUR_BASE_URL***"
  @Input() assets_url: string = "***YOUR_ASSETS_URL***"
  @Input() debug: boolean = true

  constructor(
    private tokenService: IproovTokenService,
    private supportChecker: IproovSupportCheckerService
  ) {
    this.supportChecker.checkDeviceIsSupported().then((supportCheck: iProovSupportCheck) => {
      console.log("iProov support check response", supportCheck)

      if (!supportCheck.supported) {
        console.log("Device is not supported")
        // Send user on alternative journey
        return
      }

      // Device is supported, generate token
      this.tokenService.getToken().subscribe({
        next: (response: any) => {
          this.token = response.token
          this.createIproovMe()
        },
        error: (error: any) => {
          console.error("Token fetch failed:", error)
        },
      })
    })
  }

  private createIproovMe() {
    const iproovMe = document.createElement("iproov-me")
    iproovMe.setAttribute("token", this.token)
    iproovMe.setAttribute("base_url", this.base_url)
    iproovMe.setAttribute("assets_url", this.assets_url)
    iproovMe.setAttribute("debug", this.debug ? "true" : "false")
    document.body.appendChild(iproovMe)
  }
}

Important: The assets_url attribute tells the SDK where to find its assets. Set this to the URL where your application serves the iProov SDK assets (copied from node_modules/@iproov/web-sdk to your public/assets directory).

Add any custom slots you want to use:

iproov.component.html

<template id="iproov-slots">
  <div slot="ready">Ready</div>
  <div slot="button">Click me</div>
  <div slot="passed">You Passed!!</div>
  <div slot="failed">You Failed!!</div>
</template>

Services

See backend guide for interacting with the iProov backend.

iproov-token.service.ts

import { Injectable } from "@angular/core"
import { HttpClient, HttpErrorResponse } from "@angular/common/http"
import { Observable, throwError } from "rxjs"
import { catchError, retry } from "rxjs/operators"

@Injectable({
  providedIn: "root",
})
export class IproovTokenService {
  // Replace with your backend token endpoint
  private endPoint: string = "***YOUR_BACKEND_TOKEN_ENDPOINT***"

  constructor(private http: HttpClient) {}

  private generateUsername(): string {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
      const r = (Math.random() * 16) | 0,
        v = c == "x" ? r : (r & 0x3) | 0x8
      return v.toString(16)
    })
  }

  getToken(): Observable<string> {
    return this.http
      .post<string>(
        this.endPoint,
        {
          resource: "https://iproov.app",
          user_id: `${this.generateUsername()}@example.com`,
          client: "Web SDK Angular",
        },
        {
          headers: {
            Accept: "application/json, text/plain, */*",
            "Content-Type": "application/json",
          },
        }
      )
      .pipe(retry(3), catchError(this.handleError))
  }

  handleError(error: HttpErrorResponse) {
    if (error.status === 0) {
      console.error("An error occurred:", error.error)
    } else {
      console.error(`Backend returned code ${error.status}, body was: `, error.error)
    }
    return throwError(() => new Error("Something bad happened; please try again later."))
  }
}

See full documentation for the Support Checker.

iproov-support-checker.service.ts

import { Injectable } from "@angular/core"
import { iProovSupport, iProovSupportCheck } from "@iproov/web-sdk/iProovSupport.js"

@Injectable({
  providedIn: "root",
})
export class IproovSupportCheckerService {
  public checkDeviceIsSupported(): Promise<iProovSupportCheck> {
    // Ensure assurance_type matches your token's assurance_type
    const iProovSupportChecker = new iProovSupport(window.console, { assurance_type: "genuine_presence" })
    return iProovSupportChecker.check()
  }

  public checkDeviceIsSupportedWithEvent() {
    const iProovSupportChecker = new iProovSupport(window.console, { assurance_type: "genuine_presence" })
    iProovSupportChecker.addEventListener("check", (event: any) => {
      const { supported, granted, is_native_bridge } = event.detail
      console.log("iProov support check response", event.detail)
      if (supported === false) {
        // go to fallback UX
      }
      if (supported && granted) {
        // full permission and granted, we can definitely iProov!
        if (is_native_bridge) {
          // native bridge mode detected, permission checks are not needed
        }
      }
      if (supported && granted === null) {
        // browser API support, but no permission check run (see checkWithPermission)
      }
      if (supported && granted === false) {
        // browser API support, but camera access denied
      }
    })
    iProovSupportChecker.check()
  }

  public checkDeviceIsSupportedWithPermission(): Promise<iProovSupportCheck> {
    const iProovSupportChecker = new iProovSupport()
    return iProovSupportChecker.checkWithPermission()
  }
}

Copying SDK Assets

Add a postinstall script to your package.json to copy the SDK assets:

{
  "scripts": {
    "postinstall": "cp -r node_modules/@iproov/web-sdk/iProovMe.js node_modules/@iproov/web-sdk/iProovWorker.js node_modules/@iproov/web-sdk/iProovWorkerWasm.js node_modules/@iproov/web-sdk/iProovWasm.wasm public/"
  }
}

Or add the assets to your angular.json assets configuration:

{
  "assets": [
    { "glob": "**/*", "input": "public", "output": "/" }
  ]
}

Then set assets_url to the URL where your application serves these files.

Clone this wiki locally