Back
DOCS
OverviewQuick StartEmbed WidgetEventsAPI ReferenceStatus PollingDocumentsRetentionBYOSExamples
OverviewQuick StartEmbed WidgetEventsAPI ReferenceStatus PollingDocumentsRetentionBYOSExamples
OverviewQuick StartEmbed WidgetEventsAPI ReferenceStatus PollingDocumentsRetentionBYOSExamples
  1. Home
  2. Docs
  3. Examples
  4. Vanilla JS

Vanilla JavaScript Example

A plain JavaScript class that creates and manages the AgeEvidence verification iframe. No framework dependencies required.

AgeEvidenceWidget Class

The AgeEvidenceWidget class handles iframe creation, postMessage event listening, and cleanup. It accepts configuration options and callback functions.

// AgeEvidence Verification Widget - Vanilla JS
// No framework dependencies required

class AgeEvidenceWidget {
  constructor(options) {
    this.container = options.container;
    this.externalId = options.externalId;
    this.apiKey = options.apiKey; // pk_verify_YOUR_KEY
    this.level = options.level || 'full_age';
    this.theme = options.theme || 'dark';
    this.locale = options.locale || 'en';

    this.onReady = options.onReady || (() => {});
    this.onComplete = options.onComplete || (() => {});
    this.onError = options.onError || (() => {});
    this.onCancel = options.onCancel || (() => {});

    this._handleMessage = this._handleMessage.bind(this);
    this._iframe = null;

    this.init();
  }

  init() {
    const params = new URLSearchParams({
      apiKey: this.apiKey,
      externalId: this.externalId,
      theme: this.theme,
      locale: this.locale,
      parentOrigin: window.location.origin,
    });

    const iframe = document.createElement('iframe');
    iframe.src = `https://ageevidence.com/embed/${this.level}?${params}`;
    iframe.width = '100%';
    iframe.height = '600';
    iframe.style.border = 'none';
    iframe.style.borderRadius = '12px';
    iframe.allow = 'camera';
    iframe.setAttribute('frameborder', '0');

    this.container.appendChild(iframe);
    this._iframe = iframe;

    window.addEventListener('message', this._handleMessage);
  }

  _handleMessage(event) {
    // Only trust messages from AgeEvidence
    if (event.origin !== 'https://ageevidence.com') return;

    const { type, data } = event.data;

    switch (type) {
      case 'ae:ready':
        this.onReady();
        break;
      case 'ae:complete':
        this.onComplete({
          verificationId: data.verificationId,
          status: data.status,
        });
        break;
      case 'ae:error':
        this.onError(data.error);
        break;
      case 'ae:cancel':
        this.onCancel();
        break;
    }
  }

  destroy() {
    window.removeEventListener('message', this._handleMessage);
    if (this._iframe && this._iframe.parentNode) {
      this._iframe.parentNode.removeChild(this._iframe);
    }
    this._iframe = null;
  }
}

Usage

Create an instance with your API key and user ID. Pass callback functions to handle each verification lifecycle event.

// Usage
const container = document.getElementById('verification-container');

const widget = new AgeEvidenceWidget({
  container: container,
  externalId: 'user_123',
  apiKey: 'pk_verify_YOUR_KEY',
  level: 'full_age',    // 'age_only' | 'full_age' | 'full_kyc'
  theme: 'dark',        // 'light' | 'dark' | 'auto'
  locale: 'en',         // 'en' | 'es' | 'pt' | 'fr'

  onReady: () => {
    console.log('Widget loaded');
    document.getElementById('loading')?.remove();
  },

  onComplete: (result) => {
    console.log('Verification submitted:', result.verificationId);

    // Poll status from YOUR backend (which uses the secret key)
    pollStatus('user_123');
  },

  onError: (error) => {
    console.error('Verification error:', error);
  },

  onCancel: () => {
    console.log('User cancelled');
    widget.destroy();
  },
});

// Poll YOUR backend proxy for the result
async function pollStatus(externalId) {
  const res = await fetch(`/api/check-verification?externalId=${externalId}`);
  const data = await res.json();

  if (data.data?.status === 'approved') {
    alert('Verification approved!');
    widget.destroy();
  } else if (data.data?.status === 'rejected') {
    alert('Verification rejected.');
    widget.destroy();
  } else {
    // Continue polling (see Status Polling docs for backoff)
    setTimeout(() => pollStatus(externalId), 5000);
  }
}

HTML Template

A minimal HTML page that loads the widget:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Age Verification</title>
</head>
<body>
  <h1>Verify Your Age</h1>
  <div id="loading">Loading verification widget...</div>
  <div id="verification-container"></div>

  <script src="ageevidence-widget.js"></script>
  <script>
    // Initialize the widget (see usage above)
  </script>
</body>
</html>

Cleanup

Call widget.destroy() to remove the iframe and stop listening for postMessage events. This is important when navigating away from the page in single-page applications or when the user cancels the verification.

Notes

  • Replace pk_verify_YOUR_KEY with your publishable API key from the dashboard.
  • The pollStatus function calls your own backend, not the AgeEvidence API directly.
  • See the Status Polling guide for backoff strategies.
  • This class works in all modern browsers (Chrome, Firefox, Safari, Edge).
© 2026 AgeEvidence. All rights reserved.
DocsPricingPrivacyTermsContact