Skip to content

Angular

Josselin Guillozet edited this page Oct 19, 2026 · 1 revision

Integrating the iProov Web SDK with Angular using standalone components and zoneless change detection.

ℹ️ Supported versions. We support any Angular version still receiving security patches — see Angular's actively supported versions. At the time of writing that is v20 and above.

Zoneless change detection eliminates Zone.js entirely, which removes the DOM patching that older Angular versions need a workaround for. provideZonelessChangeDetection() is stable from Angular 20.2, and zoneless is the default from Angular 21 — on those versions you can leave the provider out.

Application Config

app.config.ts

import { ApplicationConfig, provideZonelessChangeDetection } from "@angular/core"
import { provideHttpClient } from "@angular/common/http"

export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection(),
    provideHttpClient(),
  ],
}

Bootstrap

main.ts

import { bootstrapApplication } from "@angular/platform-browser"
import { appConfig } from "./app/app.config"
import { AppComponent } from "./app/app.component"

bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err))

Components

app.component.ts

import { Component } from "@angular/core"
import { IproovComponent } from "./iproov/iproov.component"

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

app.component.html

<div class="content" role="main">
  <h2>iProov Angular Example</h2>
  <app-iproov></app-iproov>
</div>

iproov.component.ts

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

@Component({
  selector: "app-iproov",
  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")
        return
      }

      this.tokenService.getToken().subscribe({
        next: (response: any) => {
          this.token = response.token
          this.createIproovMe()
        },
        error: (error) => {
          console.error("Error getting token:", 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:

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

Support Checker

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 {
  private supportChecker: iProovSupport

  constructor() {
    this.supportChecker = new iProovSupport()
  }

  async checkDeviceIsSupported(): Promise<iProovSupportCheck> {
    return await this.supportChecker.check()
  }

  async checkDeviceIsSupportedWithPermission(): Promise<iProovSupportCheck> {
    return await this.supportChecker.checkWithPermission()
  }
}

Token Service

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<any> {
    return this.http
      .post<any>(
        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."))
  }
}

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 configure assets in angular.json:

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

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

Migrating from an NgModule application

Aspect NgModule Standalone
Architecture NgModule with declarations Standalone components with imports
Change Detection Zone.js (requires zone-flags.js) Zoneless (no Zone.js patching issues)
HTTP Client HttpClientModule in imports provideHttpClient() in app config
Bootstrap platformBrowserDynamic().bootstrapModule() bootstrapApplication()
Schema CUSTOM_ELEMENTS_SCHEMA in NgModule Not needed with standalone

Clone this wiki locally