Skip to main content
@vouchmark/widget-react provides a drop-in React component with full TypeScript types. It manages script loading, lifecycle callbacks, and cleanup automatically.

Installation

npm install @vouchmark/widget-react
# or
pnpm add @vouchmark/widget-react
# or
yarn add @vouchmark/widget-react

Quick start

import { VouchmarkWidget } from "@vouchmark/widget-react";

export function VerifyButton() {
  return (
    <VouchmarkWidget
      widgetId="wgt_your_widget_id"
      publicKey="live_pk_your_public_key"
      environment="live"
      applicant={{
        email: "applicant@example.com",
        businessName: "Acme Ltd",
        registrationNumber: "RC123456",
      }}
      onSuccess={(applicant) => {
        console.log("Approved:", applicant.id, applicant.riskScore);
      }}
      onAbandon={() => {
        console.log("User closed the widget");
      }}
      onError={(error) => {
        console.error("Widget error:", error.code, error.message);
      }}
    />
  );
}
The component renders a styled button by default. When clicked, it opens the widget overlay.

Props

PropTypeRequiredDescription
widgetIdstringYesWidget ID from the dashboard. Must match the widget’s environment.
publicKeystringYesPublishable key: test_pk_… (sandbox) or live_pk_… (live).
environment"sandbox" | "live"Yes"sandbox" with test_pk_…, "live" with live_pk_…. See Environments.
applicantApplicantInputNoPre-fill applicant fields.
referenceIdstringNoYour internal reference ID.
sessionTokenstringNoSigned server token for secure mode.
localestringNoLanguage code. Default "en".
triggerReactNodeNoCustom trigger element. Defaults to a styled button.
autoOpenbooleanNoOpen immediately on mount. Default false.
onSuccess(applicant: ApplicantResult) => voidNoFires on approval.
onAbandon() => voidNoFires when user closes early.
onError(error: WidgetError) => voidNoFires on unrecoverable error.
onStepCompleted(step: StepResult) => voidNoFires after each module.
onReady() => voidNoFires when widget script is loaded.

Custom trigger

Pass any React element as the trigger prop to replace the default button:
<VouchmarkWidget
  widgetId="wgt_..."
  publicKey="live_pk_..."
  environment="live"
  trigger={<button className="btn-primary">Start KYB</button>}
  onSuccess={(applicant) => { /* ... */ }}
/>

Imperative control with useVouchmark

For programmatic open/close without rendering a trigger:
import { useVouchmark } from "@vouchmark/widget-react";

export function CustomFlow() {
  const { open, close, isReady } = useVouchmark({
    widgetId: "wgt_...",
    publicKey: "live_pk_...",
    environment: "live",
    onSuccess: (applicant) => { /* ... */ },
  });

  return (
    <button onClick={open} disabled={!isReady}>
      Begin verification
    </button>
  );
}

TypeScript types

interface ApplicantInput {
  email?: string;
  businessName?: string;
  registrationNumber?: string;
  phone?: string;
  tin?: string;
  jurisdiction?: string;
  industry?: string;
}

interface ApplicantResult {
  id: string;
  status: "approved" | "rejected" | "requires_review";
  riskScore: number | null;
  decisionReason: string | null;
  subject: ApplicantInput;
}

interface WidgetError {
  code: string;
  message: string;
}

interface StepResult {
  moduleId: string;
  status: "passed" | "failed" | "requires_review";
}

Next.js App Router

The widget component is a client component. Use it inside a "use client" boundary:
"use client";

import { VouchmarkWidget } from "@vouchmark/widget-react";

export function KybWidget() {
  return (
    <VouchmarkWidget
      widgetId={process.env.NEXT_PUBLIC_VOUCHMARK_WIDGET_ID!}
      publicKey={process.env.NEXT_PUBLIC_VOUCHMARK_PUBLIC_KEY!}
      environment="live"
      onSuccess={(applicant) => { /* redirect or update state */ }}
    />
  );
}

Server-side session creation

For signed sessions, create the token on the server and pass it as a prop:
// app/api/kyb-session/route.ts
import { Vouchmark } from "@vouchmark/node";

const vouchmark = new Vouchmark({ secretKey: process.env.VOUCHMARK_SECRET_KEY! });

export async function POST(req: Request) {
  const { email } = await req.json();
  const session = await vouchmark.sessions.create({
    widgetId: "wgt_...",
    environment: "live",
    applicant: { email },
  });
  return Response.json({ token: session.token });
}