Vanilla JavaScript SDK
Pure JavaScript implementation for Glide Identity integration without framework dependencies.
Installation
NPM/Yarn
npm install glide-web-client-sdk
# or
yarn add glide-web-client-sdk
CDN
<script src="https://cdn.jsdelivr.net/npm/glide-web-client-sdk@latest/dist/index.min.js"></script>
Basic Usage
Module Import
import { PhoneAuthClient } from 'glide-web-client-sdk';
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
},
debug: true
});
// Verify phone number
async function verifyPhone() {
try {
const result = await client.verifyPhoneNumberComplete('+14155551234', {
consent_data: {
consent_text: 'I agree to verify my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
if (result.verified) {
console.log('Phone verified successfully!');
}
} catch (error) {
console.error('Verification failed:', error);
}
}
// Get phone number
async function getPhone() {
try {
const result = await client.getPhoneNumberComplete({
consent_data: {
consent_text: 'I agree to share my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
console.log('Phone number:', result.phone_number);
} catch (error) {
console.error('Failed to get phone number:', error);
}
}
Script Tag Usage
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/glide-web-client-sdk@latest/dist/index.min.js"></script>
</head>
<body>
<button id="verifyBtn">Verify Phone</button>
<button id="getPhoneBtn">Get Phone Number</button>
<div id="result"></div>
<script>
// Initialize client
const client = new GlidePhoneAuth.PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
}
});
// Verify phone number
document.getElementById('verifyBtn').addEventListener('click', async () => {
try {
const phoneNumber = prompt('Enter phone number:');
const result = await client.verifyPhoneNumberComplete(phoneNumber, {
consent_data: {
consent_text: 'I agree to verify my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
document.getElementById('result').textContent =
result.verified ? '✅ Phone verified!' : '❌ Verification failed';
} catch (error) {
document.getElementById('result').textContent = 'Error: ' + error.message;
}
});
// Get phone number
document.getElementById('getPhoneBtn').addEventListener('click', async () => {
try {
const result = await client.getPhoneNumberComplete({
consent_data: {
consent_text: 'I agree to share my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
document.getElementById('result').textContent =
'📱 Phone: ' + result.phone_number;
} catch (error) {
document.getElementById('result').textContent = 'Error: ' + error.message;
}
});
</script>
</body>
</html>
Advanced Usage
Promise-Based Flow
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
}
});
function verifyPhoneNumber(phoneNumber) {
return client.verifyPhoneNumberComplete(phoneNumber, {
consent_data: {
consent_text: 'I agree to verify my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
})
.then(result => {
if (result.verified) {
console.log('Success!');
return result;
}
throw new Error('Verification failed');
})
.catch(error => {
console.error('Error:', error);
throw error;
});
}
Event-Driven Implementation
class PhoneAuthManager {
constructor() {
this.client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
},
onCrossDeviceDetected: () => this.handleCrossDevice(),
onRetryAttempt: (attempt, max) => this.handleRetry(attempt, max)
});
this.setupEventListeners();
}
setupEventListeners() {
// Custom events
this.events = {
onVerificationStart: [],
onVerificationComplete: [],
onVerificationError: [],
onPhoneRetrieved: []
};
}
on(event, callback) {
if (this.events[event]) {
this.events[event].push(callback);
}
}
emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
async verifyPhone(phoneNumber) {
this.emit('onVerificationStart', { phoneNumber });
try {
const result = await this.client.verifyPhoneNumberComplete(phoneNumber);
this.emit('onVerificationComplete', result);
return result;
} catch (error) {
this.emit('onVerificationError', error);
throw error;
}
}
handleCrossDevice() {
console.log('Cross-device flow detected - show QR code');
}
handleRetry(attempt, maxAttempts) {
console.log(`Retry attempt ${attempt} of ${maxAttempts}`);
}
}
// Usage
const authManager = new PhoneAuthManager();
authManager.on('onVerificationComplete', (result) => {
console.log('Verification successful:', result);
});
authManager.on('onVerificationError', (error) => {
console.error('Verification failed:', error);
});
authManager.verifyPhone('+14155551234');
Form Integration
<form id="phoneVerifyForm">
<input type="tel" id="phoneNumber" placeholder="+14155551234" required>
<button type="submit">Verify Phone</button>
<div id="loading" style="display: none;">Verifying...</div>
<div id="error" style="display: none; color: red;"></div>
<div id="success" style="display: none; color: green;">✅ Phone verified!</div>
</form>
<script>
const client = new GlidePhoneAuth.PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
}
});
const form = document.getElementById('phoneVerifyForm');
const loading = document.getElementById('loading');
const error = document.getElementById('error');
const success = document.getElementById('success');
form.addEventListener('submit', async (e) => {
e.preventDefault();
// Reset UI
loading.style.display = 'block';
error.style.display = 'none';
success.style.display = 'none';
const phoneNumber = document.getElementById('phoneNumber').value;
try {
const result = await client.verifyPhoneNumberComplete(phoneNumber, {
consent_data: {
consent_text: 'I agree to verify my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
if (result.verified) {
success.style.display = 'block';
}
} catch (err) {
error.style.display = 'block';
error.textContent = err.message;
} finally {
loading.style.display = 'none';
}
});
</script>
Browser Compatibility
// Check browser support
if (typeof navigator.credentials === 'undefined') {
console.error('Browser does not support Digital Credentials API');
// Show fallback UI
}
// Feature detection
function checkPhoneAuthSupport() {
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
}
});
return client.isSupported;
}
if (checkPhoneAuthSupport()) {
// Enable phone auth features
} else {
// Show alternative verification method
}
Error Handling
function handlePhoneAuthError(error) {
const errorMessages = {
'CARRIER_NOT_ELIGIBLE': 'Your carrier is not supported',
'PHONE_NUMBER_MISMATCH': 'Phone number does not match device',
'INVALID_PHONE_NUMBER': 'Please enter a valid phone number',
'RATE_LIMIT_EXCEEDED': 'Too many attempts. Please try again later',
'SESSION_EXPIRED': 'Session expired. Please try again',
'BROWSER_NOT_SUPPORTED': 'Your browser does not support this feature'
};
const message = errorMessages[error.code] || error.message || 'An error occurred';
// Display error to user
const errorElement = document.getElementById('error');
if (errorElement) {
errorElement.textContent = message;
errorElement.style.display = 'block';
}
console.error('Phone auth error:', error);
}
// Usage
client.verifyPhoneNumberComplete(phoneNumber)
.catch(handlePhoneAuthError);