@glideidentity/web-client-sdk
v6.0.2
Published
Glide Phone Authentication SDK for web applications
Readme
Glide Web Client SDK
The official web SDK for integrating Glide's carrier-grade phone verification into your web applications.
Features
- 🚀 Instant Verification - Direct carrier verification without SMS delays
- 🔐 Fraud Resistant - Can't be intercepted or spoofed like SMS codes
- 📱 Multi-Platform - Desktop QR codes, iOS App Clips, Android deep links
- 🎨 Customizable UI - Built-in modal with themes and view modes
- 🔧 Flexible Architecture - Use the full SDK or just the core types
- 🌐 Framework Support - React, Vue, Angular, and vanilla JavaScript
- 📦 Tree-Shakeable - Import only what you need
Installation
npm install @glideidentity/web-client-sdkQuick Start
High-Level API (Recommended)
The simplest way to integrate phone verification:
import { PhoneAuthClient, USE_CASE } from '@glideidentity/web-client-sdk';
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process',
}
});
// Get a phone number
const result = await client.authenticate({
use_case: USE_CASE.GET_PHONE_NUMBER
});
console.log('Phone:', result.phone_number);
// Or verify a specific number
const verified = await client.authenticate({
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
phone_number: '+14155551234'
});
console.log('Verified:', verified.verified);Granular API
For more control over the authentication flow:
import { PhoneAuthClient, USE_CASE } from '@glideidentity/web-client-sdk';
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process',
}
});
// Step 1: Prepare the request
const prepared = await client.prepare({
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
phone_number: '+14155551234'
});
// Step 2: Invoke authentication (shows UI based on strategy)
const invokeResult = await client.invokeSecurePrompt(prepared);
const credential = await invokeResult.credential;
// Step 3: Process the credential
const result = await client.verifyPhoneNumber(credential, invokeResult.session);
console.log('Verified:', result.verified);Configuration
Client Options
const client = new PhoneAuthClient({
// Required: Your backend endpoints
endpoints: {
prepare: '/api/phone-auth/prepare', // Prepare request endpoint
process: '/api/phone-auth/process', // Process credential endpoint
polling: '/api/phone-auth/status', // Optional: Status polling endpoint
},
// Polling configuration
pollingInterval: 2000, // Polling interval in ms (default: 2000)
maxPollingAttempts: 30, // Max attempts before timeout (default: 30)
timeout: 30000, // API request timeout in ms (default: 30000)
// Debug options
debug: false, // Enable console logging (default: false)
devtools: {
showMobileConsole: false // Show on-screen console on mobile (default: false)
}
});Invoke Options
Customize the authentication UI and behavior:
const result = await client.invokeSecurePrompt(prepared, {
// Prevent SDK from showing any UI (use your own)
preventDefaultUI: false,
// Polling configuration (overrides client config)
pollingInterval: 2000,
maxPollingAttempts: 30,
// Modal customization (for desktop QR strategy)
modalOptions: {
theme: 'auto', // 'dark' | 'light' | 'auto'
viewMode: 'toggle', // 'toggle' | 'dual' | 'pre-step'
title: 'Scan to Verify', // Custom title text
description: '', // Optional subtitle
showCloseButton: true, // Show X button
closeOnBackdropClick: true, // Close on outside click
closeOnEscape: true, // Close on Escape key
}
});Modal Customization
The SDK provides a built-in modal for desktop QR code display.
View Modes
| Mode | Description | Best For |
|------|-------------|----------|
| toggle | Single QR with iOS/Android switch | Clean, minimal UI (default) |
| dual | Side-by-side QR codes | Users who may not know their OS |
| pre-step | OS selection screen first | Guided experience |
Themes
| Theme | Description |
|-------|-------------|
| auto | Follows system preference (default) |
| dark | Dark background with light text |
| light | Light background with dark text |
Custom UI
To use your own UI instead of the built-in modal:
const result = await client.invokeSecurePrompt(prepared, {
preventDefaultUI: true
});
// For desktop strategy, display your own QR code
if (result.strategy === 'desktop') {
// Access QR data from the prepare response
const qrData = prepared.data;
displayYourQRCode(qrData.ios_qr_image, qrData.android_qr_image);
// Wait for credential
const credential = await result.credential;
// Or cancel if needed
result.cancel?.();
}Authentication Strategies
The SDK automatically selects the best strategy based on the device:
| Strategy | Platform | Description |
|----------|----------|-------------|
| ts43 | Android Chrome 128+ | Native Digital Credentials API |
| link | iOS / Android | App Clip (iOS) or carrier app (Android) |
| desktop | Desktop browsers | QR code scanned by mobile |
Strategy-Specific Handling
const result = await client.invokeSecurePrompt(prepared);
switch (result.strategy) {
case 'ts43':
// Android: Credential returned directly
const credential = await result.credential;
break;
case 'link':
// iOS: Opens App Clip, polls for completion
// Android: Opens carrier's privileged app, polls for completion
const credential = await result.credential;
// Optionally cancel polling
result.cancel?.();
break;
case 'desktop':
// Desktop: Shows QR modal, polls for completion
const credential = await result.credential;
result.cancel?.();
break;
}Framework Integration
React
import { usePhoneAuth, USE_CASE } from '@glideidentity/web-client-sdk/react';
function PhoneVerification() {
const { authenticate, isLoading, error, result } = usePhoneAuth({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process',
}
});
const handleVerify = async () => {
try {
const result = await authenticate({
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
phone_number: '+14155551234'
});
console.log('Verified:', result.verified);
} catch (err) {
console.error('Failed:', err);
}
};
return (
<button onClick={handleVerify} disabled={isLoading}>
{isLoading ? 'Verifying...' : 'Verify Phone'}
</button>
);
}Vue
<script setup>
import { usePhoneAuth, USE_CASE } from '@glideidentity/web-client-sdk/vue';
const { authenticate, isLoading, error, result } = usePhoneAuth({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process',
}
});
const handleVerify = async () => {
await authenticate({
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
phone_number: '+14155551234'
});
};
</script>
<template>
<button @click="handleVerify" :disabled="isLoading">
{{ isLoading ? 'Verifying...' : 'Verify Phone' }}
</button>
</template>Vanilla JavaScript (Browser)
<script src="https://unpkg.com/@glideidentity/web-client-sdk/dist/browser/web-client-sdk.min.js"></script>
<script>
const { PhoneAuthClient, USE_CASE } = GlideWebClientSDK;
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process',
}
});
document.getElementById('verify-btn').onclick = async () => {
const result = await client.authenticate({
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
phone_number: '+14155551234'
});
console.log('Verified:', result.verified);
};
</script>Advanced Features
Custom HTTP Headers
Add custom headers to all SDK requests:
const client = new PhoneAuthClient({
endpoints: { ... },
headers: {
common: {
'X-Custom-Header': 'your-value'
}
}
});Custom Logger
Provide your own logger implementation:
const client = new PhoneAuthClient({
endpoints: { ... },
logger: {
debug: (msg, data) => console.debug('[SDK]', msg, data),
info: (msg, data) => console.info('[SDK]', msg, data),
warn: (msg, data) => console.warn('[SDK]', msg, data),
error: (msg, data) => console.error('[SDK]', msg, data),
}
});Custom HTTP Client
Bring your own HTTP client for full control:
const client = new PhoneAuthClient({
endpoints: { ... },
httpClient: {
post: async (url, body, options) => {
const response = await yourHttpLib.post(url, body, options);
return response.data;
},
get: async (url, options) => {
const response = await yourHttpLib.get(url, options);
return response.data;
}
}
});Core Package
For advanced use cases, you can import just the types and validators without the full client:
import {
// Types
type PrepareRequest,
type PrepareResponse,
type InvokeResult,
type SessionInfo,
// Constants
USE_CASE,
AUTHENTICATION_STRATEGY,
ERROR_CODES,
// Validators
validatePhoneNumber,
validatePlmn,
// Type Guards
isTS43Strategy,
isLinkStrategy,
isDesktopStrategy,
isAuthError,
} from '@glideidentity/web-client-sdk/core';
// Use validators
const { valid, error } = validatePhoneNumber('+14155551234');
// Use type guards
if (isDesktopStrategy(result)) {
// TypeScript knows result has desktop-specific properties
}Error Handling
import { ERROR_CODES, isAuthError } from '@glideidentity/web-client-sdk';
try {
await client.authenticate({ ... });
} catch (error) {
if (isAuthError(error)) {
switch (error.code) {
case ERROR_CODES.USER_CANCELLED:
// User closed the modal or cancelled
break;
case ERROR_CODES.TIMEOUT:
// Authentication timed out
break;
case ERROR_CODES.NETWORK_ERROR:
// Network request failed
break;
default:
// Handle other errors
console.error(error.message);
}
}
}Type Reference
Use Cases
type UseCase = 'GetPhoneNumber' | 'VerifyPhoneNumber';
// Or use the constant
USE_CASE.GET_PHONE_NUMBER // 'GetPhoneNumber'
USE_CASE.VERIFY_PHONE_NUMBER // 'VerifyPhoneNumber'Prepare Request
interface PrepareRequest {
use_case: UseCase;
phone_number?: string; // Required for VerifyPhoneNumber
parent_session_id?: string; // For cross-device flows
}Invoke Result
interface InvokeResult {
strategy: 'ts43' | 'link' | 'desktop';
session: SessionInfo;
credential: Promise<AuthCredential>;
cancel?: () => void; // Available for link and desktop
}Responses
interface GetPhoneNumberResponse {
phone_number: string;
}
interface VerifyPhoneNumberResponse {
phone_number: string;
verified: boolean;
}Browser Support
| Browser | Strategy | Requirements | |---------|----------|--------------| | Chrome Android 128+ | TS43 | Digital Credentials API | | Safari iOS | Link | App Clips support | | Chrome/Edge/Firefox Desktop | Desktop | Any modern version |
Support
License
MIT
