Pular para o conteúdo principal

Instalacao do widget

O widget Veridia e um unico HTML custom element. Duas tags <script> e uma tag <veridia-widget> — essa e a instalacao completa.

O que se instala

Quando voce carrega o widget, sua pagina obtem:

  • Um custom element <veridia-widget> que voce pode colocar em qualquer lugar
  • A biblioteca face-api.js (~6 MB, usada para qualidade de selfie + deteccao de rosto)
  • O bundle do widget Veridia (~150 KB, modulo ESM)
  • Dois CustomEvents: veridia:complete e veridia:error

Os arquivos de modelo do face-api.js sao carregados lazy no primeiro uso (cerca de 14 MB) — ficam cacheados agressivamente depois.

HTML puro

A integracao mais simples possivel:

<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Verificacao KYC</title>

<!-- A ordem importa: face-api primeiro, widget depois -->
<script src="https://widget.xxuxe.online/face-api.js"></script>
<script type="module" src="https://widget.xxuxe.online/veridia-widget.min.js"></script>
</head>
<body>
<main>
<h1>Verifique sua identidade</h1>

<veridia-widget
id="kyc"
publishable-key="qv_pub_test_SUA_KEY"
api-base="https://api.xxuxe.online"
user-ref="customer-12345"
country="BR"
document-type="national_id"
locale="pt">
</veridia-widget>
</main>

<script>
document.getElementById('kyc').addEventListener('veridia:complete', (e) => {
console.log('Verification ID:', e.detail.verificationId);
// Envie o ID ao seu backend para obter o veredicto
});
</script>
</body>
</html>

React (Create React App, Vite, etc.)

import { useEffect, useRef } from 'react';

export function VeridiaVerification({ userRef, onComplete, onError }) {
const widgetRef = useRef(null);

useEffect(() => {
const node = widgetRef.current;
if (!node) return;

const completeHandler = (e) => onComplete?.(e.detail);
const errorHandler = (e) => onError?.(e.detail);

node.addEventListener('veridia:complete', completeHandler);
node.addEventListener('veridia:error', errorHandler);

return () => {
node.removeEventListener('veridia:complete', completeHandler);
node.removeEventListener('veridia:error', errorHandler);
};
}, [onComplete, onError]);

return (
<veridia-widget
ref={widgetRef}
publishable-key={import.meta.env.VITE_VERIDIA_KEY}
api-base="https://api.xxuxe.online"
user-ref={userRef}
country="BR"
document-type="national_id"
locale="pt"
/>
);
}

Carregue os scripts uma vez em index.html:

<script src="https://widget.xxuxe.online/face-api.js"></script>
<script type="module" src="https://widget.xxuxe.online/veridia-widget.min.js"></script>

TypeScript: adicione isto a um arquivo *.d.ts para que JSX aceite o custom element:

declare namespace JSX {
interface IntrinsicElements {
'veridia-widget': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement> & {
'publishable-key': string;
'api-base': string;
'user-ref'?: string;
'country'?: string;
'document-type'?: string;
'submitted-full-name'?: string;
'require-doc-back'?: string;
'locale'?: string;
'accent-color'?: string;
},
HTMLElement
>;
}
}

Next.js

No Next.js, custom elements precisam carregar apos a hidratacao. Use next/script com strategy="afterInteractive":

// app/layout.tsx (App Router)
import Script from 'next/script';

export default function RootLayout({ children }) {
return (
<html lang="pt">
<body>
{children}
<Script
src="https://widget.xxuxe.online/face-api.js"
strategy="afterInteractive"
/>
<Script
src="https://widget.xxuxe.online/veridia-widget.min.js"
type="module"
strategy="afterInteractive"
/>
</body>
</html>
);
}
// app/onboarding/kyc/page.tsx
'use client';

import { useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';

export default function KycPage() {
const widgetRef = useRef(null);
const router = useRouter();

useEffect(() => {
const node = widgetRef.current;
if (!node) return;

const handler = async (e) => {
const { verificationId } = e.detail;

// Envie ao seu backend
await fetch('/api/kyc/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ verificationId }),
});

router.push('/onboarding/success');
};

node.addEventListener('veridia:complete', handler);
return () => node.removeEventListener('veridia:complete', handler);
}, [router]);

return (
<main>
<h1>Verifique sua identidade</h1>
<veridia-widget
ref={widgetRef}
publishable-key={process.env.NEXT_PUBLIC_VERIDIA_KEY}
api-base="https://api.xxuxe.online"
locale="pt"
/>
</main>
);
}

Vue 3

Vue trata custom elements automaticamente. Sem necessidade de config especial:

<template>
<veridia-widget
ref="widget"
:publishable-key="publishableKey"
api-base="https://api.xxuxe.online"
:user-ref="userRef"
locale="pt"
/>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const props = defineProps({
publishableKey: { type: String, required: true },
userRef: { type: String, required: true },
});

const emit = defineEmits(['complete', 'error']);
const widget = ref(null);

const completeHandler = (e) => emit('complete', e.detail);
const errorHandler = (e) => emit('error', e.detail);

onMounted(() => {
widget.value?.addEventListener('veridia:complete', completeHandler);
widget.value?.addEventListener('veridia:error', errorHandler);
});

onUnmounted(() => {
widget.value?.removeEventListener('veridia:complete', completeHandler);
widget.value?.removeEventListener('veridia:error', errorHandler);
});
</script>

Carregue os scripts em index.html:

<script src="https://widget.xxuxe.online/face-api.js"></script>
<script type="module" src="https://widget.xxuxe.online/veridia-widget.min.js"></script>

Angular

No Angular, voce precisa permitir custom elements no seu modulo:

// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';

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

Depois use em templates:

<veridia-widget
#widget
[attr.publishable-key]="publishableKey"
api-base="https://api.xxuxe.online"
[attr.user-ref]="userRef"
locale="pt"
(veridia:complete)="onComplete($event)"
(veridia:error)="onError($event)">
</veridia-widget>

Mobile webview

O widget funciona dentro do iOS WebView e Android WebView. Dois requisitos:

  1. Permissoes de camera: o app host deve conceder acesso a camera. No iOS, WKWebView.allowsInlineMediaPlayback = true. No Android, override onPermissionRequest para conceder RESOURCE_VIDEO_CAPTURE.
  2. HTTPS: mesmo em WebView, o widget recusa rodar em origens inseguras.

Troubleshooting

"Este widget esta mal configurado"

Mais comum: seu dominio nao esta na lista de allowed origins do dashboard.

Fix: dashboard → API Keys → editar sua key → adicionar o dominio (ex: https://seuapp.com, ou http://localhost:3000 para dev).

O widget carrega mas nunca mostra o botao Comecar

Geralmente face-api.js falhou ao carregar. Verifique o console do browser por 404s ou erros CSP.

Fix: verifique as URLs dos scripts:

  • https://widget.xxuxe.online/face-api.js deve retornar 200
  • https://widget.xxuxe.online/veridia-widget.min.js deve retornar 200

"Camera nao disponivel"

O usuario negou permissao de camera, ou a pagina nao e HTTPS.

Fix: garanta que sua pagina seja servida sobre HTTPS. Browsers bloqueiam camera em http:// (exceto localhost).

As capturas saem borradas / dispara o flag de qualidade

Dispositivos mobile auto-focam melhor que laptops. Diga aos usuarios que tomem seu tempo e mantenham firme.

Se sua audiencia usa principalmente desktops, ajuste accent-color e de clareza UI, mas aceite que alguns usuarios vao precisar de 2-3 retries.

React: warning sobre atributo desconhecido

React nao reconhece custom elements por padrao. Adicione a declaracao TypeScript acima, ou defina suppressHydrationWarning no parent.

Next.js: document is not defined durante build

O widget usa APIs do browser. Marque sua pagina como client component ('use client') e garanta que os scripts usem strategy="afterInteractive".

Erros CSP (Content Security Policy)

Se seu site tem CSP estrito, adicione estas directivas:

script-src 'self' https://widget.xxuxe.online;
connect-src 'self' https://api.xxuxe.online https://*.r2.cloudflarestorage.com;
img-src 'self' blob: data: https://widget.xxuxe.online;
media-src 'self' blob:;
worker-src blob:;

O connect-src para R2 e necessario para upload direto de imagens do browser.

O widget mostra o idioma errado

Defina o atributo locale explicitamente:

<veridia-widget locale="pt">

Default e o locale do browser, fallback ingles.

Verificando a instalacao

Uma instalacao funcionando deve passar este checklist:

CheckComo verificar
Scripts carregamTab Network de DevTools — ambos 200
Custom element registradodocument.querySelector('veridia-widget') retorna um elemento
Botao Comecar apareceVisivel botao "Comecar" / "Start"
Prompt de camera apareceApos clicar em Comecar
Captura tem sucessoO evento veridia:complete dispara com um verificationId

Proximos passos