npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@voxket-ai/voxket-live

v1.1.30

Published

A React widget for embedding Voxket-powered audio/video/chat experiences.

Readme

🎯 Voxket Web SDK (@voxket-ai/voxket-live)

The Complete AI Agent Integration Solution - Seamlessly embed voice, video, and chat experiences powered by Voxket AI agents into any web application.

NPM Version License: MIT TypeScript

🌟 Key Features

🔥 Multi-Modal AI Interactions

  • 🎤 Voice Conversations - Real-time voice chat with AI agents
  • 💬 Text Chat - Instant messaging with typing indicators and message history
  • 📹 Video Calls - Face-to-face conversations with video support
  • 📺 Screen Sharing - Share your screen with AI agents for enhanced support

🎨 Flexible Display Options

  • 🪟 Widget Mode - Embedded widget for seamless integration
  • 🚀 Popup Mode - Floating chat bubble with customizable positioning
  • 🖥️ Fullscreen Mode - Immersive full-screen experience
  • 📱 Responsive Design - Works perfectly on desktop and mobile

🎭 Rich Theming System

  • 🌙 Dark Theme - Modern dark interface
  • ☀️ Light Theme - Clean light interface
  • 💎 Vox Theme - Custom branded Voxket theme
  • 🎨 Custom Themes - Create your own themes with full CSS control

Powerful Integration Options

🔧 1. Simple Widget Integration (React)

Perfect for React applications with minimal setup.

🚀 2. Client SDK Integration (Any Framework)

Use the powerful VoxketClient for programmatic control with vanilla JavaScript, Vue, Angular, or any framework.

📊 3. Advanced React Integration

Full React ecosystem with providers, hooks, and compound components.

🛠️ Advanced Features

🎪 Interactive Components (RPC System)

  • 🎯 Agent-Triggered UI - Agents can display custom React components
  • 📝 Forms & Surveys - Collect user input through interactive forms
  • 📊 Data Visualization - Show charts, tables, and rich content
  • 🎮 Custom Interactions - Build any interactive experience

📈 Session Analytics & Logging

  • 📊 Real-time Metrics - Monitor session quality and performance
  • 🔍 Event Logging - Track all user interactions and system events
  • 💾 Data Export - Export session data for analysis
  • ⏱️ Session Timers - Track session duration and activity

🔌 Event System

  • 📡 Connection Events - Track connection status and quality
  • 👥 Participant Events - Monitor who joins and leaves
  • 🎵 Media Events - Handle track publishing/unpublishing
  • 💬 Message Events - Real-time message and transcription events
  • 🤖 Agent Events - Monitor agent state (thinking, speaking, idle)

🎛️ Media Controls

  • 🎤 Microphone Control - Mute/unmute with visual feedback
  • 📷 Camera Control - Enable/disable video with device selection
  • 📺 Screen Share - Start/stop screen sharing
  • 🎧 Audio Devices - Select input/output devices
  • 📹 Video Devices - Choose camera sources

💼 Business-Ready Features

  • 🔐 Enterprise Security - HIPAA-compliant options available
  • 🌐 Multi-Language Support - Internationalization ready
  • 📱 Cross-Platform - Works on all modern browsers and devices
  • ⚡ High Performance - Built on LiveKit for optimal real-time performance
  • 🛡️ Error Handling - Robust error recovery and user feedback
  • 🔄 Auto-Reconnection - Automatic connection recovery

🚀 Quick Start

📦 Installation

npm install @voxket-ai/voxket-live
yarn add @voxket-ai/voxket-live

🎯 Option 1: Simple Widget (React)

Perfect for React apps - drop in the widget component:

import React from 'react';
import VoxketWidget from '@voxket-ai/voxket-live';

function App() {
  return (
    <div>
      <h1>My App</h1>
      <VoxketWidget
        agentId="your-agent-id"
        baseUrl="https://your.voxket.api"
        appId="your-app-id"
        appSecret="your-app-secret"
        participantName="User"
        modalities={['voice', 'chat']} // Choose: voice, chat, video, screen_share
        theme="vox" // Options: dark, light, vox
        displayType="widget" // Options: widget, popup, fullscreen
        width="400px"
        height="600px"
      />
    </div>
  );
}

🔧 Option 2: Client SDK (Any Framework)

Use with vanilla JavaScript, Vue, Angular, or any framework:

import { VoxketClient } from '@voxket-ai/voxket-live';

// Create client
const client = new VoxketClient({
  appId: "your-app-id",
  appSecret: "your-app-secret",
  baseUrl: "https://your.voxket.api",
  agentId: "your-agent-id",
  participantName: "User"
});

// Connect and render UI
await client.connect();
client.renderUI({
  target: '#voxket-container', // CSS selector or HTMLElement
  modality: ['voice', 'chat'],
  theme: 'dark',
  displayType: 'widget',
  autoStart: true
});

🏗️ Option 3: Advanced React Integration

Full React ecosystem with providers and hooks:

import { VoxketProvider, useVoxket } from '@voxket-ai/voxket-live';

function App() {
  return (
    <VoxketProvider config={{
      appId: "your-app-id",
      appSecret: "your-app-secret", 
      baseUrl: "https://your.voxket.api"
    }}>
      <MyComponent />
    </VoxketProvider>
  );
}

function MyComponent() {
  const { client, connect, session } = useVoxket();
  
  const handleStartChat = async () => {
    await connect();
    const session = await client.startSession("agent-id", {
      modalities: ['chat'],
      participantName: "User"
    });
  };

  return (
    <div>
      <button onClick={handleStartChat}>Start Chat</button>
      {session && <p>Session active: {session.id}</p>}
    </div>
  );
}

🎛️ Display Types

🪟 Widget Mode

Embedded widget that fits naturally into your application:

<VoxketWidget 
  displayType="widget"
  width="400px" 
  height="600px"
  // ... other props
/>

🚀 Popup Mode

Floating chat bubble that can be positioned anywhere:

<VoxketWidget 
  displayType="popup"
  popupPosition="bottom-right" // top-left, top-right, bottom-left, bottom-right
  popupTriggerText="Need Help?"
  onPopupToggle={(isOpen) => console.log('Popup:', isOpen)}
  // ... other props
/>

🖥️ Fullscreen Mode

Immersive full-screen experience:

<VoxketWidget 
  displayType="fullscreen"
  onDisplayTypeChange={(type) => console.log('Display changed to:', type)}
  // ... other props
/>

🎨 Themes & Customization

🎭 Built-in Themes

// Dark theme
<VoxketWidget theme="dark" />

// Light theme  
<VoxketWidget theme="light" />

// Voxket branded theme
<VoxketWidget theme="vox" />

🎨 Custom Styling

<VoxketWidget 
  className="my-custom-widget"
  width="500px"
  height="700px"
  // Custom CSS classes and dimensions
/>

💬 Session Events & Analytics

📊 Basic Session Tracking

<VoxketWidget
  onSessionStart={(sessionId) => {
    console.log('Session started:', sessionId);
    analytics.track('voxket_session_started', { sessionId });
  }}
  onSessionEnd={(metrics) => {
    console.log('Session ended:', metrics);
    analytics.track('voxket_session_ended', { 
      duration: metrics.duration,
      messageCount: metrics.messageCount 
    });
  }}
  enableSessionLogging={true}
/>

🔍 Advanced Session Monitoring

import { SessionLog, SessionMetrics } from '@voxket-ai/voxket-live';

function MyApp() {
  const [logs, setLogs] = useState<SessionLog[]>([]);
  const [metrics, setMetrics] = useState<SessionMetrics | null>(null);

  return (
    <VoxketWidget
      onSessionLogsUpdate={(logs) => {
        setLogs(logs);
        // Send to your analytics service
        analytics.track('session_events', { eventCount: logs.length });
      }}
      onSessionMetricsUpdate={(metrics) => {
        setMetrics(metrics);
        // Update your dashboard
        updateDashboard(metrics);
      }}
      // ... other props
    />
  );
}

🎪 Interactive Components (RPC System)

📝 Agent-Triggered UI Components

Agents can trigger custom React components during conversations:

import { VoxketClient } from '@voxket-ai/voxket-live';

const client = new VoxketClient(config);

// Register a custom form component
await client.registerFrontendRPC(
  'customer_survey', // Method name the agent calls
  SurveyComponent,   // Your React component
  'modal'           // Presentation mode: embedded, modal, fullscreen
);

// Your custom component
function SurveyComponent({ handler, data }) {
  const [rating, setRating] = useState(0);

  const handleSubmit = () => {
    handler.didSuccess({ 
      survey_response: rating,
      feedback: "Great service!" 
    });
  };

  return (
    <div>
      <h3>Rate your experience</h3>
      <StarRating value={rating} onChange={setRating} />
      <button onClick={handleSubmit}>Submit</button>
      <button onClick={handler.dismissView}>Skip</button>
    </div>
  );
}

🎯 Interactive UI Examples

  • 📋 Forms & Surveys - Collect user feedback
  • 📊 Data Visualization - Show charts and graphs
  • 🛒 Product Catalogs - Display interactive product lists
  • 📅 Appointment Scheduling - Calendar integrations
  • 💳 Payment Flows - Secure payment processing
  • 🎮 Custom Games - Interactive experiences

📡 Event System

🔌 Connection Events

client.on('connection.connected', () => {
  console.log('✅ Connected to Voxket');
});

client.on('connection.disconnected', (reason) => {
  console.log('❌ Disconnected:', reason);
});

client.on('connection.error', (error) => {
  console.error('🚨 Connection error:', error);
});

🔔 Custom Event System

📡 Register Event Emitters

Register custom event emitters to listen for LiveKit text stream topics:

import { VoxketClient } from '@voxket-ai/voxket-live';

const client = new VoxketClient(config);

// Register an event emitter for custom events
client.registerEventEmitter('custom_event_topic', (data) => {
  console.log('Custom event received:', data);
  // Handle your custom business logic
  handleCustomEvent(data);
});

// Register multiple event emitters
client.registerEventEmitter('user_action', (actionData) => {
  console.log('User action:', actionData);
  analytics.track('user_action', actionData);
});

client.registerEventEmitter('system_notification', (notification) => {
  showNotification(notification);
});

🎯 Event Listener Registration

Register event listeners for any SDK events with automatic cleanup:

// Register event listeners with automatic unsubscribe
const unsubscribe = client.registerEventListener('chat.message.received', (message) => {
  console.log('New message:', message);
  updateUI(message);
});

// Manual cleanup when needed
unsubscribe();

// Register multiple listeners
client.registerEventListener('connection.connected', () => {
  console.log('Connected to Voxket!');
  updateConnectionStatus('connected');
});

client.registerEventListener('agent.thinking', () => {
  showTypingIndicator();
});

🏢 Business Integration Examples

Real-time Notifications

// Listen for agent-triggered notifications
client.registerEventEmitter('agent_notification', (data) => {
  // Show toast notification
  showToast({
    title: data.title,
    message: data.message,
    type: data.type
  });
});

// Listen for system updates
client.registerEventEmitter('system_update', (updateInfo) => {
  if (updateInfo.type === 'maintenance') {
    showMaintenanceWarning(updateInfo.schedule);
  }
});

Custom Analytics Integration

// Track custom business events
client.registerEventEmitter('business_event', (eventData) => {
  // Send to your analytics platform
  analytics.track(eventData.event_name, {
    ...eventData.properties,
    timestamp: new Date().toISOString(),
    session_id: client.getCurrentSession()?.id
  });
});

// Example: Track user interactions
client.registerEventEmitter('user_interaction', (interaction) => {
  mixpanel.track('Voxket User Interaction', {
    interaction_type: interaction.type,
    interaction_data: interaction.data,
    user_id: getCurrentUserId()
  });
});

Workflow Automation

// Trigger business workflows
client.registerEventEmitter('workflow_trigger', (workflowData) => {
  switch (workflowData.workflow_type) {
    case 'lead_qualification':
      triggerLeadQualificationWorkflow(workflowData.lead_data);
      break;
    case 'support_escalation':
      escalateToHumanAgent(workflowData.ticket_data);
      break;
    case 'appointment_booking':
      processAppointmentRequest(workflowData.appointment_data);
      break;
  }
});

💬 Chat & Messaging Events

client.on('chat.message.received', (message) => {
  console.log('💬 New message:', message);
  displayMessage(message);
});

client.on('chat.message.sent', (message) => {
  console.log('📤 Message sent:', message);
  logOutgoingMessage(message);
});

client.on('transcription.received', (transcription) => {
  console.log('🎤 Voice transcription:', transcription);
  displayTranscription(transcription);
});

🤖 Agent State Events

client.on('agent.thinking', () => {
  showTypingIndicator();
});

client.on('agent.speaking', () => {
  showSpeakingIndicator();
});

client.on('agent.connected', () => {
  console.log('🤖 Agent joined the conversation');
});

🎵 Media Events

client.on('track.muted', ({ source, enabled }) => {
  console.log(`🔇 ${source} muted:`, !enabled);
});

client.on('track.unmuted', ({ source, enabled }) => {
  console.log(`🔊 ${source} unmuted:`, enabled);
});

🎛️ Media Controls

🎤 Microphone Control

// Toggle microphone
await client.toggleMicrophone();

// Explicit control
await client.setMicrophoneEnabled(true);  // Unmute
await client.setMicrophoneEnabled(false); // Mute

// Check current state
const isMuted = !client.isMicrophoneEnabled;

📷 Camera Control

// Toggle camera
await client.toggleCamera();

// Explicit control  
await client.enableCamera();
await client.disableCamera();

// Check current state
const isCameraOn = client.isCameraEnabled;

📺 Screen Sharing

// Start screen share
await client.startScreenShare();

// Stop screen share
await client.stopScreenShare();

// Check if screen sharing is active
const isSharing = client.isScreenShareEnabled;

🎧 Device Management

// Get available devices
const audioDevices = await client.getAudioInputDevices();
const videoDevices = await client.getVideoInputDevices();

// Switch devices
await client.setAudioInputDevice(deviceId);
await client.setVideoInputDevice(deviceId);

💼 Business Integration Examples

🛒 E-commerce Customer Support

const supportClient = new VoxketClient({
  appId: "ecommerce-app",
  appSecret: "your-secret",
  baseUrl: "https://api.voxket.com",
  agentId: "customer-support",
  
  onMessageReceived: (message) => {
    // Log customer interactions
    analytics.track('customer_support_message', {
      content: message.content,
      timestamp: message.timestamp
    });
  }
});

// Add to product pages
document.getElementById('help-button').onclick = async () => {
  await supportClient.connect();
  supportClient.renderUI({
    target: '#support-widget',
    modality: ['chat'],
    theme: 'light',
    displayType: 'popup',
    popupPosition: 'bottom-right'
  });
};

🏥 Healthcare Patient Portal

const healthcareClient = new VoxketClient({
  appId: "healthcare-portal",
  appSecret: "hipaa-compliant-secret",
  baseUrl: "https://secure.voxket.com",
  agentId: "patient-support",
  participantName: getCurrentPatient().name,
  
  onSessionStart: (sessionId) => {
    // HIPAA-compliant logging
    auditLogger.log({
      event: 'patient_session_started',
      sessionId,
      patientId: getCurrentPatient().id,
      timestamp: new Date()
    });
  }
});

// Secure patient communications
await healthcareClient.connect();
healthcareClient.renderUI({
  target: '#patient-support',
  modality: ['chat'], // Text-only for security
  theme: 'light'
});

💰 Financial Services

const financeClient = new VoxketClient({
  appId: "banking-app",
  appSecret: "secure-secret",
  baseUrl: "https://secure-api.voxket.com",
  agentId: "financial-advisor",
  
  onSessionStart: (sessionId) => {
    // Compliance logging
    complianceLogger.record({
      type: 'customer_interaction_start',
      sessionId,
      customerId: getCurrentCustomer().id
    });
  }
});

// Financial consultation widget
await financeClient.connect();
financeClient.renderUI({
  target: '#advisor-chat',
  modality: ['voice', 'video'],
  theme: 'dark',
  displayType: 'fullscreen'
});

🛠️ Advanced Usage

🔄 Session Management

// Start a session with specific configuration
const session = await client.startSession("agent-id", {
  participantName: "John Doe",
  modalities: ['voice', 'chat'],
  metadata: {
    customerType: "premium",
    department: "support"
  }
});

// Get current session
const currentSession = client.getCurrentSession();

// End session manually
await client.endSession();

📊 Custom Analytics Integration

client.on('session.created', (session) => {
  analytics.track('voxket_session_created', {
    sessionId: session.id,
    agentId: session.agentId,
    modalities: session.activeModalities
  });
});

client.on('chat.message.received', (message) => {
  analytics.track('voxket_message_received', {
    messageType: message.sender.type,
    contentLength: message.content.length,
    sessionId: client.getCurrentSession()?.id
  });
});

🔌 Multiple Widget Instances

// Support chat
const supportClient = new VoxketClient(supportConfig);
supportClient.renderUI({ 
  target: '#support-widget',
  modality: ['chat'] 
});

// Sales call
const salesClient = new VoxketClient(salesConfig);  
salesClient.renderUI({
  target: '#sales-widget',
  modality: ['voice', 'video']
});

🎯 HTML/Vanilla JavaScript Integration

Use the SDK without any framework:

<!DOCTYPE html>
<html>
<head>
    <title>Voxket Integration</title>
    <script src="https://unpkg.com/@voxket-ai/voxket-live@latest/dist/index.js"></script>
</head>
<body>
    <div id="voxket-container"></div>
    
    <script>
        const { VoxketClient } = window.VoxketLive;
        
        const client = new VoxketClient({
            appId: 'your-app-id',
            appSecret: 'your-secret',
            baseUrl: 'https://api.voxket.com',
            agentId: 'support-agent'
        });
        
        client.connect().then(() => {
            client.renderUI({
                target: '#voxket-container',
                modality: ['chat'],
                theme: 'light'
            });
        });
    </script>
</body>
</html>

🔧 VoxketClient API Reference

🏗️ Constructor Options

interface VoxketClientConfig {
  // Required
  appId: string;        // Your Voxket App ID
  appSecret: string;    // Your Voxket App Secret  
  baseUrl: string;      // Voxket API base URL
  
  // Optional
  agentId?: string;     // Default agent ID
  participantName?: string; // Default participant name
  modalities?: SessionModality[]; // Default modalities
  debug?: boolean;      // Enable debug logging
  
  // Event Callbacks
  onConnected?: () => void;
  onDisconnected?: (reason?: string) => void; 
  onError?: (error: Error) => void;
  onMessageReceived?: (message: ChatMessage) => void;
  onTranscriptionReceived?: (transcription: TranscriptionSegment) => void;
  onSessionStateChanged?: (state: SessionState) => void;
}

📞 Connection Methods

// Connect to Voxket services
await client.connect(agentId?, participantName?, modalities?);

// Disconnect and cleanup
await client.disconnect();

// Check connection status
const isConnected = client.connected;
const state = client.getConnectionState();

🎬 Session Management

// Start a new session
const session = await client.startSession(agentId, {
  participantName: "User",
  modalities: ['voice', 'chat'],
  metadata: { customData: "value" }
});

// Get current session
const current = client.getCurrentSession();

// End current session
await client.endSession();

🎨 UI Rendering

// Render UI widget
client.renderUI({
  target: '#container',           // CSS selector or HTMLElement
  modality: ['voice', 'chat'],    // Supported modalities
  theme: 'dark',                  // Theme selection
  component: 'widget',            // Component type
  displayType: 'popup',           // Display mode
  autoStart: true,                // Auto-start session
  width: '400px',                 // Custom width
  height: '600px',                // Custom height
  onDisplayTypeChange: (type) => console.log(type)
});

// Remove UI
client.removeUI('#container');
client.removeAllUI();

💬 Messaging

// Send text message
await client.sendMessage("Hello agent!");

// Send with metadata
await client.sendChatMessage("Hello", { priority: "high" });

// Send file attachments (images only)
await client.sendAttachment(imageFile);
await client.sendAttachments([file1, file2]);

🎵 Media Control Methods

// Microphone control
await client.toggleMicrophone();
await client.setMicrophoneEnabled(true);
const isMuted = !client.isMicrophoneEnabled;

// Camera control
await client.enableCamera();
await client.disableCamera();
await client.toggleCamera();
const isCameraOn = client.isCameraEnabled;

// Screen sharing
await client.startScreenShare();
await client.stopScreenShare();
const isSharing = client.isScreenShareEnabled;

// Device management
const audioDevices = await client.getAudioInputDevices();
const videoDevices = await client.getVideoInputDevices();
await client.setAudioInputDevice(deviceId);
await client.setVideoInputDevice(deviceId);

Event System Methods

// Register custom event emitter
client.registerEventEmitter(
  topic: string,
  handler: (data: string) => void
): void

// Register event listener with cleanup
client.registerEventListener<K extends keyof VoxketEvents>(
  eventName: K,
  callback: (data: any) => void
): () => void

// Example usage
const unsubscribe = client.registerEventListener('chat.message.received', (msg) => {
  console.log('Message:', msg);
});

// Cleanup
unsubscribe();

�👥 Participant Management

// Get participants
const localParticipant = client.getLocalParticipant();
const remoteParticipants = client.getRemoteParticipants();
const allParticipants = client.getParticipants();

// Check permissions
const permissions = client.getPublishPermissions();
const canPublish = client.canPublishSource('microphone');

// Get media tracks
const micTrack = client.getMicrophoneTrack();
const cameraTrack = client.getCameraTrack();
const screenTrack = client.getScreenShareTrack();

🎪 Interactive Components Deep Dive

📝 Creating Custom Interactive Components

import React, { useState } from 'react';
import { VoxketInteractiveViewProps } from '@voxket-ai/voxket-live';

function SurveyForm({ handler, data }: VoxketInteractiveViewProps) {
  const [rating, setRating] = useState(0);
  const [feedback, setFeedback] = useState('');

  const handleSubmit = () => {
    handler?.didSuccess({
      survey_rating: rating,
      customer_feedback: feedback,
      submitted_at: new Date().toISOString()
    });
  };

  const handleSkip = () => {
    handler?.dismissView(); // Sends decline response to agent
  };

  return (
    <div className="p-6 bg-white rounded-lg shadow-lg">
      <h3 className="text-lg font-semibold mb-4">
        {data?.title || 'Rate Your Experience'}
      </h3>
      
      <div className="mb-4">
        <label className="block text-sm font-medium mb-2">
          How would you rate our service?
        </label>
        <div className="flex gap-2">
          {[1,2,3,4,5].map(num => (
            <button
              key={num}
              onClick={() => setRating(num)}
              className={`w-10 h-10 rounded ${
                rating >= num ? 'bg-blue-500 text-white' : 'bg-gray-200'
              }`}
            >
              {num}
            </button>
          ))}
        </div>
      </div>

      <div className="mb-4">
        <label className="block text-sm font-medium mb-2">
          Additional feedback (optional):
        </label>
        <textarea
          value={feedback}
          onChange={(e) => setFeedback(e.target.value)}
          className="w-full p-2 border rounded"
          rows={3}
        />
      </div>

      <div className="flex gap-2 justify-end">
        <button 
          onClick={handleSkip}
          className="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded"
        >
          Skip
        </button>
        <button 
          onClick={handleSubmit}
          disabled={rating === 0}
          className="px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
        >
          Submit
        </button>
      </div>
    </div>
  );
}

// Register the component
await client.registerFrontendRPC(
  'customer_satisfaction_survey',
  SurveyForm,
  'modal' // Can be 'embedded', 'modal', or 'fullscreen'
);

🛒 E-commerce Product Showcase

function ProductCatalog({ handler, data }: VoxketInteractiveViewProps) {
  const [selectedProduct, setSelectedProduct] = useState(null);
  
  const products = data?.products || [];

  const handleSelectProduct = (product: any) => {
    handler?.didSuccess({
      selected_product: product,
      action: 'add_to_cart'
    });
  };

  return (
    <div className="p-4">
      <h3 className="text-xl font-bold mb-4">Recommended Products</h3>
      <div className="grid grid-cols-2 gap-4">
        {products.map((product: any) => (
          <div key={product.id} className="border rounded-lg p-4">
            <img 
              src={product.image} 
              alt={product.name}
              className="w-full h-32 object-cover rounded mb-2"
            />
            <h4 className="font-semibold">{product.name}</h4>
            <p className="text-gray-600">${product.price}</p>
            <button
              onClick={() => handleSelectProduct(product)}
              className="mt-2 w-full bg-blue-500 text-white py-2 rounded"
            >
              Add to Cart
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}

📅 Appointment Scheduler

function AppointmentBooker({ handler, data }: VoxketInteractiveViewProps) {
  const [selectedSlot, setSelectedSlot] = useState('');
  const [contactInfo, setContactInfo] = useState({ name: '', email: '' });
  
  const availableSlots = data?.available_slots || [];

  const handleBooking = () => {
    handler?.didSuccess({
      appointment: {
        slot: selectedSlot,
        contact: contactInfo,
        type: data?.appointment_type,
        booked_at: new Date().toISOString()
      }
    });
  };

  return (
    <div className="p-6 bg-white rounded-lg">
      <h3 className="text-lg font-semibold mb-4">Book Appointment</h3>
      
      <div className="mb-4">
        <label className="block text-sm font-medium mb-2">
          Available Time Slots:
        </label>
        <div className="grid grid-cols-2 gap-2">
          {availableSlots.map((slot: string) => (
            <button
              key={slot}
              onClick={() => setSelectedSlot(slot)}
              className={`p-2 rounded border ${
                selectedSlot === slot 
                  ? 'bg-blue-500 text-white' 
                  : 'bg-gray-50 hover:bg-gray-100'
              }`}
            >
              {slot}
            </button>
          ))}
        </div>
      </div>

      <div className="mb-4">
        <input
          type="text"
          placeholder="Your Name"
          value={contactInfo.name}
          onChange={(e) => setContactInfo({...contactInfo, name: e.target.value})}
          className="w-full p-2 border rounded mb-2"
        />
        <input
          type="email"
          placeholder="Email Address"
          value={contactInfo.email}
          onChange={(e) => setContactInfo({...contactInfo, email: e.target.value})}
          className="w-full p-2 border rounded"
        />
      </div>

      <button
        onClick={handleBooking}
        disabled={!selectedSlot || !contactInfo.name || !contactInfo.email}
        className="w-full bg-green-500 text-white py-2 rounded disabled:opacity-50"
      >
        Book Appointment
      </button>
    </div>
  );
}

📊 Session Analytics & Metrics

📈 Session Metrics Interface

interface SessionMetrics {
  sessionId: string;
  startTime: Date;
  endTime?: Date;
  duration?: number;           // Duration in milliseconds
  totalMessages: number;       // Total messages exchanged
  connectionIssues: number;    // Network issues count
  participantCount: number;    // Number of participants
  events: SessionLog[];        // All session events
}

interface SessionLog {
  timestamp: Date;
  event: string;              // Event type
  data?: any;                 // Event data
  sessionId?: string;         // Associated session
  participantId?: string;     // Participant who triggered event
}

📊 Analytics Integration Examples

// Google Analytics 4
client.on('session.created', (session) => {
  gtag('event', 'voxket_session_start', {
    session_id: session.id,
    agent_id: session.agentId,
    modalities: session.activeModalities.join(',')
  });
});

// Mixpanel
client.on('chat.message.received', (message) => {
  mixpanel.track('Voxket Message Received', {
    session_id: client.getCurrentSession()?.id,
    message_type: message.sender.type,
    message_length: message.content.length,
    timestamp: message.timestamp
  });
});

// Custom Analytics
const analyticsTracker = {
  trackSession: (event: string, data: any) => {
    fetch('/api/analytics', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ event, data, timestamp: new Date() })
    });
  }
};

client.on('session.ended', (session, metrics) => {
  analyticsTracker.trackSession('session_completed', {
    duration: metrics.duration,
    message_count: metrics.totalMessages,
    quality_score: calculateQualityScore(metrics)
  });
});

🛠️ Enterprise Features

🔐 Security & Compliance

// HIPAA-compliant configuration
const healthcareClient = new VoxketClient({
  appId: "healthcare-app",
  appSecret: "hipaa-compliant-secret",
  baseUrl: "https://secure-api.voxket.com",
  agentId: "patient-support",
  
  // Disable session logging for compliance
  enableSessionLogging: false,
  
  onSessionStart: (sessionId) => {
    // HIPAA audit logging
    complianceLogger.logPatientInteraction({
      sessionId,
      patientId: getCurrentPatient().id,
      timestamp: new Date(),
      actionType: 'SESSION_START'
    });
  }
});

// Only use secure text-based modalities
await healthcareClient.connect();
healthcareClient.renderUI({
  modality: ['chat'], // Text only for security
  theme: 'light',
  enableSessionLogging: false
});

🏢 Multi-tenant Architecture

class TenantManager {
  private clients: Map<string, VoxketClient> = new Map();

  async createTenantClient(tenantId: string, config: any) {
    const client = new VoxketClient({
      appId: config.appId,
      appSecret: config.appSecret,
      baseUrl: config.baseUrl,
      agentId: `${tenantId}-agent`,
      
      onMessageReceived: (message) => {
        // Tenant-specific message handling
        this.handleTenantMessage(tenantId, message);
      }
    });

    this.clients.set(tenantId, client);
    return client;
  }

  getTenantClient(tenantId: string) {
    return this.clients.get(tenantId);
  }

  private handleTenantMessage(tenantId: string, message: any) {
    // Tenant-specific analytics, logging, etc.
    console.log(`Tenant ${tenantId} received message:`, message);
  }
}

// Usage
const tenantManager = new TenantManager();
const client = await tenantManager.createTenantClient('acme-corp', {
  appId: 'acme-app-id',
  appSecret: 'acme-secret',
  baseUrl: 'https://acme.voxket.com'
});

🔄 Advanced Session Management

// Session persistence across page reloads
class SessionManager {
  private static SESSION_KEY = 'voxket_session';

  static saveSession(session: VoxketSession) {
    localStorage.setItem(this.SESSION_KEY, JSON.stringify({
      id: session.id,
      agentId: session.agentId,
      startedAt: session.startedAt,
      metadata: session.metadata
    }));
  }

  static restoreSession(): VoxketSession | null {
    const saved = localStorage.getItem(this.SESSION_KEY);
    if (saved) {
      try {
        return JSON.parse(saved);
      } catch {
        return null;
      }
    }
    return null;
  }

  static clearSession() {
    localStorage.removeItem(this.SESSION_KEY);
  }
}

// Restore previous session on page load
const client = new VoxketClient(config);
const previousSession = SessionManager.restoreSession();

if (previousSession) {
  // Attempt to reconnect to existing session
  try {
    await client.connect();
    // Check if session is still valid and restore UI state
  } catch (error) {
    SessionManager.clearSession();
    // Start fresh session
  }
}

🔧 Troubleshooting

Common Issues

1. Widget Not Displaying

// Check console for errors and verify configuration
const client = new VoxketClient({
  appId: "your-app-id", // ✅ Make sure this is correct
  appSecret: "your-app-secret", // ✅ Make sure this is correct
  baseUrl: "https://api.voxket.com", // ✅ Check URL is correct
  debug: true // ✅ Enable debug logging
});

2. Connection Failures

client.on('connection.error', (error) => {
  console.error('Connection failed:', error);
  
  // Common fixes:
  // - Verify appId and appSecret are correct
  // - Check baseUrl is accessible
  // - Ensure network connectivity
  // - Check for CORS issues in browser console
});

client.on('connection.disconnected', (reason) => {
  console.log('Disconnected reason:', reason);
  
  // Auto-reconnect logic
  setTimeout(() => {
    client.connect().catch(console.error);
  }, 5000);
});

3. Microphone/Camera Permission Issues

// Handle permission errors gracefully
client.on('connection.error', (error) => {
  if (error.code === 'PERMISSION_DENIED') {
    showUserMessage('Please allow microphone/camera access to continue');
  }
});

// Request permissions explicitly
navigator.mediaDevices.getUserMedia({ 
  audio: true, 
  video: true 
}).then(() => {
  console.log('Permissions granted');
}).catch((error) => {
  console.error('Permission denied:', error);
});

4. React Strict Mode Issues

// For React 18 Strict Mode, wrap your app properly
function App() {
  const [client, setClient] = useState<VoxketClient | null>(null);
  
  useEffect(() => {
    // Only create client once
    if (!client) {
      const newClient = new VoxketClient(config);
      setClient(newClient);
    }
    
    return () => {
      // Cleanup on unmount
      client?.disconnect();
    };
  }, []);
  
  if (!client) return <div>Loading...</div>;
  
  return <VoxketWidget voxketClient={client} {...props} />;
}

🐛 Debug Mode

// Enable comprehensive debugging
const client = new VoxketClient({
  // ... config
  debug: true
});

// Monitor all events
client.onAny((eventName, ...args) => {
  console.log(`🔍 Event: ${eventName}`, args);
});

// Check connection state
console.log('Connection state:', client.getConnectionState());
console.log('Current session:', client.getCurrentSession());
console.log('Is connected:', client.connected);

🛠️ Performance Optimization

// Optimize for production
const client = new VoxketClient({
  // ... config
  debug: false, // Disable debug logs
});

// Lazy load the widget
const LazyVoxketWidget = lazy(() => import('@voxket-ai/voxket-live'));

function App() {
  return (
    <Suspense fallback={<div>Loading chat...</div>}>
      <LazyVoxketWidget {...props} />
    </Suspense>
  );
}

// Preload on user interaction
const preloadChat = () => {
  import('@voxket-ai/voxket-live').then(() => {
    console.log('Voxket SDK preloaded');
  });
};

// Call preloadChat() on hover or focus events

🎯 Best Practices

🏗️ Application Architecture

1. Client Instance Management

// ✅ Good: Single client instance
class VoxketManager {
  private static instance: VoxketClient | null = null;

  static getInstance(config: VoxketClientConfig): VoxketClient {
    if (!this.instance) {
      this.instance = new VoxketClient(config);
    }
    return this.instance;
  }

  static cleanup() {
    if (this.instance) {
      this.instance.disconnect();
      this.instance = null;
    }
  }
}

// ❌ Bad: Multiple client instances
function BadComponent() {
  const [client] = useState(() => new VoxketClient(config)); // Creates new client each render
}

2. Error Handling

// ✅ Comprehensive error handling
async function initializeVoxket() {
  try {
    await client.connect();
    client.renderUI({ target: '#voxket-widget' });
  } catch (error) {
    if (error.code === 'AUTHENTICATION_FAILED') {
      showError('Invalid credentials');
    } else if (error.code === 'NETWORK_ERROR') {
      showError('Connection failed - please try again');
    } else {
      showError('Something went wrong');
    }
    
    // Log for debugging
    console.error('Voxket initialization failed:', error);
  }
}

3. Event Cleanup

// ✅ Always cleanup event listeners
useEffect(() => {
  const handleMessage = (message: ChatMessage) => {
    // Handle message
  };
  
  client.on('chat.message.received', handleMessage);
  
  return () => {
    client.off('chat.message.received', handleMessage);
  };
}, [client]);

📱 User Experience

1. Loading States

function ChatWidget() {
  const [isConnecting, setIsConnecting] = useState(false);
  const [connectionError, setConnectionError] = useState('');

  const initChat = async () => {
    setIsConnecting(true);
    setConnectionError('');
    
    try {
      await client.connect();
      client.renderUI({ target: '#chat' });
    } catch (error) {
      setConnectionError('Failed to connect. Please try again.');
    } finally {
      setIsConnecting(false);
    }
  };

  return (
    <div>
      {isConnecting && <div>Connecting to support...</div>}
      {connectionError && <div className="error">{connectionError}</div>}
      <button onClick={initChat} disabled={isConnecting}>
        Start Chat
      </button>
      <div id="chat"></div>
    </div>
  );
}

2. Progressive Enhancement

// Start with basic features, enhance based on capabilities
const client = new VoxketClient(config);

// Check agent capabilities
const agentInfo = client.getCurrentAgentInfo();
const supportedModalities = agentInfo?.modality_supported || ['chat'];

// Render appropriate UI
client.renderUI({
  modality: supportedModalities.includes('voice') 
    ? ['voice', 'chat'] 
    : ['chat'],
  theme: userPreferences.theme || 'vox'
});

3. Accessibility

// Ensure keyboard navigation and screen reader support
<VoxketWidget
  className="voxket-accessible"
  // Widget automatically includes ARIA labels and keyboard support
  {...props}
/>

/* CSS for better accessibility */
.voxket-accessible {
  /* Ensure focus indicators are visible */
  --focus-ring-color: #3b82f6;
}

.voxket-accessible *:focus {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

🔒 Security

1. Credential Management

// ✅ Use environment variables
const client = new VoxketClient({
  appId: process.env.VOXKET_APP_ID,
  appSecret: process.env.VOXKET_APP_SECRET,
  baseUrl: process.env.VOXKET_BASE_URL
});

// ✅ For browser apps, use backend proxy
async function getVoxketCredentials() {
  const response = await fetch('/api/voxket-auth', {
    headers: {
      'Authorization': `Bearer ${userToken}`
    }
  });
  return response.json();
}

2. Content Security Policy

<!-- Add CSP headers for security -->
<meta http-equiv="Content-Security-Policy" 
      content="connect-src 'self' wss://*.voxket.com https://*.voxket.com;">

🌐 Framework Integration Examples

⚛️ React with TypeScript

import React, { useCallback, useEffect, useState } from 'react';
import VoxketWidget, { 
  VoxketWidgetProps, 
  VoxketClient, 
  SessionMetrics 
} from '@voxket-ai/voxket-live';

interface Props {
  agentId: string;
  userId: string;
  userRole: 'customer' | 'admin';
}

export function CustomerSupport({ agentId, userId, userRole }: Props) {
  const [sessionMetrics, setSessionMetrics] = useState<SessionMetrics | null>(null);
  const [isActive, setIsActive] = useState(false);

  const handleSessionStart = useCallback((sessionId: string) => {
    setIsActive(true);
    console.log('Support session started:', sessionId);
  }, []);

  const handleSessionEnd = useCallback((metrics: SessionMetrics) => {
    setSessionMetrics(metrics);
    setIsActive(false);
    console.log('Session ended:', metrics);
  }, []);

  const widgetProps: VoxketWidgetProps = {
    agentId,
    baseUrl: process.env.NEXT_PUBLIC_VOXKET_BASE_URL!,
    appId: process.env.NEXT_PUBLIC_VOXKET_APP_ID!,
    appSecret: process.env.NEXT_PUBLIC_VOXKET_APP_SECRET!,
    participantName: `User-${userId}`,
    theme: 'vox',
    modalities: ['chat', 'voice'],
    displayType: 'popup',
    popupPosition: 'bottom-right',
    onSessionStart: handleSessionStart,
    onSessionEnd: handleSessionEnd
  };

  return (
    <div className="customer-support">
      {isActive && (
        <div className="status-indicator">
          🟢 Support session active
        </div>
      )}
      
      <VoxketWidget {...widgetProps} />
      
      {sessionMetrics && (
        <div className="session-summary">
          <h4>Session Summary</h4>
          <p>Duration: {Math.round(sessionMetrics.duration! / 1000)}s</p>
          <p>Messages: {sessionMetrics.totalMessages}</p>
        </div>
      )}
    </div>
  );
}

🖖 Vue 3 Composition API

<template>
  <div class="vue-voxket">
    <button @click="initializeChat" :disabled="isLoading">
      Start Support Chat
    </button>
    <div ref="voxketContainer" class="voxket-container"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { VoxketClient } from '@voxket-ai/voxket-live';

const voxketContainer = ref<HTMLElement>();
const isLoading = ref(false);
let client: VoxketClient | null = null;

const initializeChat = async () => {
  if (!client || !voxketContainer.value) return;
  
  isLoading.value = true;
  
  try {
    await client.connect();
    client.renderUI({
      target: voxketContainer.value,
      modality: ['chat'],
      theme: 'light',
      autoStart: true
    });
  } catch (error) {
    console.error('Failed to initialize chat:', error);
  } finally {
    isLoading.value = false;
  }
};

onMounted(() => {
  client = new VoxketClient({
    appId: import.meta.env.VITE_VOXKET_APP_ID,
    appSecret: import.meta.env.VITE_VOXKET_APP_SECRET,
    baseUrl: import.meta.env.VITE_VOXKET_BASE_URL,
    agentId: 'vue-support-agent'
  });
});

onUnmounted(() => {
  if (client) {
    client.removeAllUI();
    client.disconnect();
  }
});
</script>

🅰️ Angular Component

// voxket.service.ts
import { Injectable } from '@angular/core';
import { VoxketClient } from '@voxket-ai/voxket-live';

@Injectable({ providedIn: 'root' })
export class VoxketService {
  private client: VoxketClient;

  constructor() {
    this.client = new VoxketClient({
      appId: environment.voxketAppId,
      appSecret: environment.voxketAppSecret,
      baseUrl: environment.voxketBaseUrl
    });
  }

  async startChat(containerId: string, agentId: string) {
    await this.client.connect();
    this.client.renderUI({
      target: `#${containerId}`,
      agentId,
      modality: ['chat'],
      theme: 'dark'
    });
  }

  disconnect() {
    this.client.removeAllUI();
    this.client.disconnect();
  }
}

// chat.component.ts
@Component({
  selector: 'app-chat',
  template: `
    <div class="chat-container">
      <button (click)="startChat()" [disabled]="isLoading">
        {{ isLoading ? 'Connecting...' : 'Start Chat' }}
      </button>
      <div id="angular-voxket-container"></div>
    </div>
  `
})
export class ChatComponent implements OnDestroy {
  isLoading = false;

  constructor(private voxketService: VoxketService) {}

  async startChat() {
    this.isLoading = true;
    try {
      await this.voxketService.startChat('angular-voxket-container', 'support-agent');
    } finally {
      this.isLoading = false;
    }
  }

  ngOnDestroy() {
    this.voxketService.disconnect();
  }
}

🏪 Svelte Integration

<!-- VoxketChat.svelte -->
<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import { VoxketClient } from '@voxket-ai/voxket-live';
  
  export let agentId: string;
  export let theme: 'dark' | 'light' | 'vox' = 'vox';
  
  let container: HTMLElement;
  let client: VoxketClient;
  let isConnected = false;
  
  onMount(() => {
    client = new VoxketClient({
      appId: import.meta.env.VITE_VOXKET_APP_ID,
      appSecret: import.meta.env.VITE_VOXKET_APP_SECRET,
      baseUrl: import.meta.env.VITE_VOXKET_BASE_URL,
      
      onConnected: () => {
        isConnected = true;
      },
      
      onDisconnected: () => {
        isConnected = false;
      }
    });
  });
  
  async function startChat() {
    if (!client || !container) return;
    
    try {
      await client.connect();
      client.renderUI({
        target: container,
        agentId,
        modality: ['chat'],
        theme
      });
    } catch (error) {
      console.error('Chat initialization failed:', error);
    }
  }
  
  onDestroy(() => {
    if (client) {
      client.removeAllUI();
      client.disconnect();
    }
  });
</script>

<div class="svelte-voxket">
  <button on:click={startChat} disabled={!client}>
    {isConnected ? '💬 Chat Active' : 'Start Chat'}
  </button>
  
  <div bind:this={container} class="chat-container"></div>
</div>

<style>
  .chat-container {
    width: 400px;
    height: 600px;
    border-radius: 12px;
    overflow: hidden;
  }
</style>

🚀 Deployment & Production

🏭 Production Checklist

// ✅ Production configuration
const client = new VoxketClient({
  appId: process.env.VOXKET_APP_ID!, // From secure environment
  appSecret: process.env.VOXKET_APP_SECRET!, // From secure environment
  baseUrl: process.env.VOXKET_BASE_URL!, // Production URL
  debug: false, // Disable debug logs
  
  // Error tracking
  onError: (error) => {
    // Send to error monitoring service (Sentry, etc.)
    console.error('Voxket error:', error);
    errorTracker.captureException(error);
  }
});

// ✅ Health check endpoint
app.get('/health/voxket', async (req, res) => {
  try {
    // Test Voxket API connectivity
    const response = await fetch(`${process.env.VOXKET_BASE_URL}/health`);
    if (response.ok) {
      res.status(200).json({ status: 'healthy' });
    } else {
      res.status(503).json({ status: 'unhealthy' });
    }
  } catch (error) {
    res.status(503).json({ status: 'error', error: error.message });
  }
});

📊 Monitoring & Analytics

// Production monitoring setup
class VoxketMonitoring {
  static setupMonitoring(client: VoxketClient) {
    // Connection monitoring
    client.on('connection.connected', () => {
      this.trackEvent('voxket_connected');
    });
    
    client.on('connection.error', (error) => {
      this.trackError('voxket_connection_error', error);
    });
    
    // Session analytics
    client.on('session.created', (session) => {
      this.trackEvent('voxket_session_start', {
        session_id: session.id,
        agent_id: session.agentId
      });
    });
    
    // Performance monitoring
    const startTime = Date.now();
    client.on('connection.connected', () => {
      const connectionTime = Date.now() - startTime;
      this.trackTiming('voxket_connection_time', connectionTime);
    });
  }
  
  private static trackEvent(event: string, data?: any) {
    // Send to your analytics service
    analytics.track(event, data);
  }
  
  private static trackError(event: string, error: Error) {
    // Send to error monitoring
    errorTracker.captureException(error, { tags: { component: 'voxket' } });
  }
  
  private static trackTiming(metric: string, duration: number) {
    // Send to performance monitoring
    performanceTracker.timing(metric, duration);
  }
}

// Apply monitoring
VoxketMonitoring.setupMonitoring(client);

📚 API Reference Summary

🏗️ Core Classes

  • VoxketClient - Main SDK client for programmatic control
  • VoxketWidget - React component for easy integration
  • VoxketProvider - React context provider for advanced usage

🎨 Display Types

  • widget - Embedded widget mode
  • popup - Floating popup mode
  • fullscreen - Full-screen overlay mode

🎭 Themes

  • vox - Default Voxket branded theme
  • dark - Dark mode theme
  • light - Light mode theme
  • Custom - Create your own theme object

🎪 Modalities

  • voice - Voice conversations with transcription
  • chat - Text-based messaging
  • video - Video calls with camera support
  • screen_share - Screen sharing capability

📡 Event Categories

  • Connection Events - connection.*
  • Session Events - session.*
  • Chat Events - chat.*
  • Agent Events - agent.*
  • Media Events - track.*
  • RPC Events - rpc.*

🤝 Community & Support

📖 Documentation

🆘 Getting Help

🧪 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📄 License

MIT License - see LICENSE file for details.


🎉 Ready to Get Started?

  1. Install the SDK: npm install @voxket-ai/voxket-live
  2. Get your credentials from the Voxket Dashboard
  3. Choose your integration method (Widget, Client SDK, or Advanced React)
  4. Start building amazing AI-powered experiences!

💡 Need help?

Check out our Quick Start Guide or join our Discord community for real-time support!


Built with ❤️ by the Voxket team