Inlined

The inline flow allows loading the Persona Inquiry flow directly within your page. It is intended for desktop flows that do not want a dropdown modal experience.

Verifying individuals with the Inlined Flow can be easily achieved with a short code snippet. You’ll only need your template ID which can be found in the Integration Section of your Dashboard.

The latest version of the SDK is: Persona SDK latest

Inlining the flow

Persona can be integrated with the following code snippet. Remember to replace templateId with your organization’s template ID.

html
1<!DOCTYPE html>
2<html>
3 <body>
4 <script type="text/javascript" src="../../packages/persona/dist/persona.js"></script>
5 <script>
6 window.addEventListener("DOMContentLoaded", function() {
7 const containerId =
8 "persona-widget-" +
9 new Array(16)
10 .fill(undefined)
11 .map(() => Math.floor(Math.random() * 35).toString(35))
12 .join("");
13 const templateId = "<template id>";
14 Persona.setupEvents(containerId, {
15 onLoad: function () {
16 console.log("On Load");
17 },
18 onReady: function () {
19 console.log("On Ready");
20 },
21 onComplete: function () {
22 console.log("On Complete");
23 },
24 onEvent: function () {
25 console.log("On Event");
26 },
27 onCancel: function () {
28 console.log("On Cancel");
29 },
30 onError: function () {
31 console.log("On Error");
32 },
33 templateId,
34 });
35 const personaIframe = document.querySelector("#persona-inline-iframe");
36 Persona.setupIframe(personaIframe, containerId, "inline", {
37 templateId,
38 });
39 });
40 </script>
41 <iframe id="persona-inline-iframe"></iframe>
42 </body>
43</html>

To permit the Persona iframe to render on your domain, see Security > Embedding the Persona iframe.

In order to have multiple active widgets currently, make sure to give each widget a unique containerId

Styling

For more granular or dynamic styling, the iframe can be targeted via CSS. We recommend targeting a selector provided by your app such as .your-classname > iframe instead of relying on Persona class names to avoid unexpected breakage.

We recommend using a minimum height of 650px and a minimum width of 400px to ensure contents are properly displayed without excessive horizontal wrapping or scrolling.

Handling loading state

The Persona iframe starts loading when the Persona component is rendered. Thus, there will be a delay between when the component is rendered and when the Inquiry flow content is displayed. We recommend using the onReady client callback to detect when loading is completed, and handling any loading UI outside of Persona.

Alternatively, if your use case allows it, you can pre-render the Persona component and visually hide it with CSS until it needs to be used.

More Examples

Angular

angular.json
1{
2 "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 "version": 1,
4 "newProjectRoot": "projects",
5 "projects": {
6 "first-app": {
7 "projectType": "application",
8 "schematics": { /* ... */ },
9 // ... other properties
10 "architect": {
11 "build": {
12 "builder": "@angular/build:application",
13 "options": {
14 "outputPath": "dist/first-app",
15 "index": "src/index.html",
16 "browser": "src/main.ts",
17 "polyfills": ["zone.js"],
18 "tsConfig": "tsconfig.app.json",
19 "inlineStyleLanguage": "scss",
20 "assets": ["src/favicon.ico", "src/assets"],
21 "styles": ["src/styles.css"],
22 "scripts": [
23 // ADD HERE
24 "node_modules/persona/dist/persona.js"
25 ]
26 },
27 "configurations": { /* ... */ }
28 },
29 "serve": { /* serve settings */ }
30 }
31 }
32}
Component
1import { Component, AfterViewInit } from "@angular/core";
2
3@Component({
4 selector: "app-root",
5 imports: [],
6 template: `
7 <div id="persona-example-body">
8 <h1>Persona Inline App Example</h1>
9 <iframe id="persona-inline-iframe"></iframe>
10 </div>
11 `,
12 styleUrls: ["./app.css"],
13 styles: `
14 iframe {
15 width: 800px;
16 height: 650px;
17 }
18
19 [id="persona-example-body"] {
20 display: flex;
21 flex-direction: column;
22 align-items: center;
23 }
24 `,
25})
26export class App implements AfterViewInit {
27 title = "Persona Inline App Example";
28
29 ngAfterViewInit(): void {
30 const Persona = (window as any).Persona;
31
32 const containerId =
33 "persona-widget-" +
34 new Array(16)
35 .fill(undefined)
36 .map(() => Math.floor(Math.random() * 35).toString(35))
37 .join("");
38
39 const templateId = "<template id>";
40 Persona.setupEvents(containerId, {
41 onLoad: function () {
42 console.log("On Load");
43 },
44 onReady: function () {
45 console.log("On Ready");
46 },
47 onComplete: function () {
48 console.log("On Complete");
49 },
50 onEvent: function () {
51 console.log("On Event");
52 },
53 onCancel: function () {
54 console.log("On Cancel");
55 },
56 onError: function () {
57 console.log("On Error");
58 },
59 templateId,
60 });
61 const personaIframe = document.querySelector("#persona-inline-iframe");
62 Persona.setupIframe(personaIframe, containerId, "inline", {
63 templateId,
64 });
65 }
66}