Integration Guide

This guide covers how to integrate the Xident SDK into your website with detailed examples for various frameworks.

Prerequisites

  • A Xident API key (from your dashboard)
  • A callback URL on your domain (HTTPS required in production)
  • Backend code to verify the returned token

Quick Start

1. Add the Script Tag

<script
  src="https://sdk.xident.io/xident.min.js"
  data-api-key="pk_live_your_api_key"
  data-callback-url="https://yoursite.com/verified"
></script>

2. Add a Verify Button

<button onclick="Xident.start()">Verify Your Age</button>

3. Handle the Callback

When verification completes, users are redirected to your callback URL with query parameters:

https://yoursite.com/verified?token=abc123&status=success

Configuration Options

Script Tag Attributes

Attribute Required Description
data-api-key Yes Your public API key
data-callback-url Yes Where to redirect after verification
data-verify-url No Custom verification URL (default: verify.xident.io)
data-theme No light, dark, or auto
data-locale No Language code (e.g., en, es, de)

StartOptions

Xident.start({
  userId: 'user-123',           // Track which user is verifying
  metadata: {                   // Custom data (available in token response)
    orderId: 'order-456',
    plan: 'premium'
  },
  newTab: false                 // Open in new tab instead of redirect
});

Programmatic Configuration

For SPAs or dynamic configuration:

// Configure manually (instead of script attributes)
Xident.configure({
  apiKey: 'pk_live_xxx',
  callbackUrl: 'https://yoursite.com/verified',
  theme: 'dark',
  locale: 'de'
});

// Check if configured
if (Xident.isConfigured()) {
  Xident.start();
}

// Get current config
const config = Xident.getConfig();
console.log(config.apiKey);

Framework Examples

React

// components/VerifyButton.jsx
import { useEffect, useState } from 'react';

export function VerifyButton({ userId, onSuccess }) {
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    const checkReady = () => {
      if (window.Xident) {
        if (!window.Xident.isConfigured()) {
          window.Xident.configure({
            apiKey: import.meta.env.VITE_XIDENT_API_KEY,
            callbackUrl: `${window.location.origin}/verified`
          });
        }
        setIsReady(true);
      }
    };

    if (window.Xident) {
      checkReady();
    } else {
      window.addEventListener('DOMContentLoaded', checkReady);
    }

    return () => window.removeEventListener('DOMContentLoaded', checkReady);
  }, []);

  const handleClick = () => {
    if (!isReady) return;
    window.Xident.start({
      userId,
      metadata: { source: 'react-app' }
    });
  };

  return (
    <button onClick={handleClick} disabled={!isReady}>
      {isReady ? 'Verify Age' : 'Loading...'}
    </button>
  );
}

Vue

<!-- components/VerifyButton.vue -->
<template>
  <button @click="handleVerify" :disabled="!isReady">
    {{ isReady ? 'Verify Age' : 'Loading...' }}
  </button>
</template>

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

const props = defineProps(['userId']);
const isReady = ref(false);

onMounted(() => {
  const init = () => {
    if (window.Xident) {
      if (!window.Xident.isConfigured()) {
        window.Xident.configure({
          apiKey: import.meta.env.VITE_XIDENT_API_KEY,
          callbackUrl: `${window.location.origin}/verified`
        });
      }
      isReady.value = true;
    }
  };

  if (document.readyState === 'complete') {
    init();
  } else {
    window.addEventListener('load', init);
  }
});

const handleVerify = () => {
  window.Xident.start({ userId: props.userId });
};
</script>

Next.js

// components/VerifyButton.tsx
'use client';

import { useEffect, useState } from 'react';
import Script from 'next/script';

declare global {
  interface Window {
    Xident: {
      configure: (config: { apiKey: string; callbackUrl: string }) => void;
      start: (options?: { userId?: string }) => void;
      isConfigured: () => boolean;
    };
  }
}

export function VerifyButton({ userId }: { userId: string }) {
  const [isReady, setIsReady] = useState(false);

  const handleScriptLoad = () => {
    window.Xident.configure({
      apiKey: process.env.NEXT_PUBLIC_XIDENT_API_KEY!,
      callbackUrl: `${window.location.origin}/verified`
    });
    setIsReady(true);
  };

  const handleVerify = () => {
    window.Xident.start({ userId });
  };

  return (
    <>
      <Script
        src="https://sdk.xident.io/xident.min.js"
        onLoad={handleScriptLoad}
      />
      <button onClick={handleVerify} disabled={!isReady}>
        Verify Age
      </button>
    </>
  );
}

Error Handling

try {
  Xident.start();
} catch (error) {
  // Possible errors:
  // - "SDK not configured. Call configure() first."
  // - "callbackUrl is required."
  // - "Invalid callbackUrl. Must be a valid HTTPS URL."

  console.error('Xident error:', error.message);
  showError('Unable to start verification. Please try again.');
}

Security Best Practices

  1. Use HTTPS - Callback URLs must be HTTPS (except localhost for development)
  2. Verify Tokens Server-Side - Never trust client-side verification results
  3. Protect Your Secret Key - Keep XIDENT_SECRET_KEY on the backend only
  4. Domain Validation - Xident validates that callback URLs match your API key's registered domain
  5. Token Expiration - Tokens expire in 5 minutes and are single-use

Testing

Development Mode

<!-- Use localhost for testing -->
<script
  src="https://sdk.xident.io/xident.min.js"
  data-api-key="pk_test_xxx"
  data-callback-url="http://localhost:3000/verified"
></script>

Debug Information

console.log('Xident Version:', Xident.version);
console.log('Is Configured:', Xident.isConfigured());
console.log('Current Config:', Xident.getConfig());

Public API

Method Description
Xident.start(options?) Redirect to verification
Xident.configure(config) Manual configuration
Xident.isConfigured() Check if ready
Xident.getConfig() Get current config
Xident.version SDK version

Related Documentation