โจ Why Direct Integration?
โ Advantages of Direct Integration
- No iframe issues: No resizing, scrolling, or CORS problems
- Better UX: Smoother animations and interactions
- Mobile-friendly: Perfect responsive behavior
- Full control: Easy customization with attributes
- Faster loading: Direct integration loads faster
โ ๏ธOld iframe approach (NOT recommended)
- โ Fixed size - can't adapt to widget state
- โ Scrollbars and overflow issues
- โ CORS and security complications
- โ Poor mobile experience
๐ Features
๐จ Customizable
Full control over colors, position, size, and language
๐ฑ Responsive
Works perfectly on desktop, tablet, and mobile
โก Fast
Lightweight and loads instantly
๐ Secure
No cross-origin issues, direct integration
๐งช Try Different Widget Configurations
Test Channel ID: 959b51c4-3cf1-4f7d-9a8d-392e522a343f
Use preset buttons or customize your own configuration:
Preset Configurations
Custom Configuration
โก Quick Start
Step 1: Get Your Widget Code
// Fetch widget code from API const response = await fetch( 'https://backend-dev.dmva.acebox.eu/v1/voice-widget/YOUR_CHANNEL_ID/direct' ); const data = await response.json(); // Get the full code ready to paste console.log(data.data.full_code);
Step 2: Paste Code Before Closing </body> Tag
<!DOCTYPE html> <html> <head> <title>My Website</title> </head> <body> <!-- Your page content --> <h1>Welcome to My Website</h1> <!-- Voice Widget - paste before closing body tag --> <elevenlabs-convai agent-id="agent_xxx" background-color="#007bff" widget-position="bottom-right" widget-size="small" override-language="en" hide-branding="true"> </elevenlabs-convai> <script src="https://unpkg.com/@elevenlabs/convai-widget-embed" async></script> </body> </html>
Step 3: Enjoy! ๐
That's it! The widget will automatically appear on your page and adapt to user interactions.
๐จ Customization Options
Query Parameters
// All available customization options GET /v1/voice-widget/{channelId}/direct?theme=dark&position=bottom-left&language=ru&uilanguage=ru&color=#ff6b35&avatar=https://example.com/avatar.png&hidebranding=true // Parameters: // - theme: light | dark | custom (default: light) // - position: bottom-right | bottom-left | top-right | top-left (default: bottom-right) // - language: en | ru | pl | de | fr | etc. (voice language, default: en) // - uilanguage: en | ru | pl | etc. (widget UI language, defaults to language) // - color: hex color code like #ff6b35 (default: #007bff) // - avatar: URL to custom avatar image (default: phone icon) // - hidebranding: true | false (default: true) // NOTE: Widget size is always SMALL (mini) for optimal UX
Widget Attributes
<elevenlabs-convai agent-id="agent_xxx" <!-- Required: ElevenLabs agent ID --> background-color="#007bff" <!-- Widget background color --> text-color="#ffffff" <!-- Widget text color --> widget-position="bottom-right" <!-- Position on page --> widget-size="small" <!-- Always small (mini) - fixed --> override-language="en" <!-- Voice language --> hide-branding="true"> <!-- Hide ElevenLabs branding --> </elevenlabs-convai>
๐ง Framework Integration
React Example
import React, { useEffect } from 'react'; function VoiceWidget() { useEffect(() => { // Load ElevenLabs script const script = document.createElement('script'); script.src = 'https://unpkg.com/@elevenlabs/convai-widget-embed'; script.async = true; document.body.appendChild(script); return () => { document.body.removeChild(script); }; }, []); return ( <elevenlabs-convai agent-id="agent_xxx" background-color="#007bff" widget-position="bottom-right" hide-branding="true"> </elevenlabs-convai> ); } export default VoiceWidget;
Vue.js Example
<template> <elevenlabs-convai :agent-id="agentId" background-color="#007bff" widget-position="bottom-right" hide-branding="true"> </elevenlabs-convai> </template> <script> export default { data() { return { agentId: 'agent_xxx' } }, mounted() { const script = document.createElement('script'); script.src = 'https://unpkg.com/@elevenlabs/convai-widget-embed'; script.async = true; document.body.appendChild(script); } } </script>
Vanilla JavaScript
// Fetch widget configuration and inject into page async function loadVoiceWidget(channelId) { try { const response = await fetch( `https://backend-dev.dmva.acebox.eu/v1/voice-widget/${channelId}/direct` ); const data = await response.json(); // Create widget element const widget = document.createElement('div'); widget.innerHTML = data.data.html_snippet; document.body.appendChild(widget); // Load script const script = document.createElement('script'); script.src = 'https://unpkg.com/@elevenlabs/convai-widget-embed'; script.async = true; document.body.appendChild(script); console.log('โ Voice widget loaded successfully!'); } catch (error) { console.error('โ Failed to load voice widget:', error); } } // Load widget on page load loadVoiceWidget('YOUR_CHANNEL_ID');
๐ฌ Live Demo
Try it yourself!
The voice widget is already integrated on this page. Look for the widget button in the bottom-right corner!
Test Channel: Customer Support Demo
Language: English
Theme: Blue (#007bff)
๐ API Reference
Response Format
{
"status": "success",
"data": {
"agent_id": "agent_xxx",
"channel_id": "uuid",
"channel_name": "Customer Support",
"agent_name": "Kate",
"tenant_name": "Your Company",
// Ready-to-use code snippets
"html_snippet": "<elevenlabs-convai ...></elevenlabs-convai>",
"script_tag": "<script src='...'></script>",
"full_code": "Complete code ready to paste",
// Configuration used
"configuration": { ... },
// Available options
"customization_options": { ... },
// Framework examples
"usage_examples": {
"html": "...",
"react": "...",
"vue": "..."
}
}
}
โ๏ธ Comparison: Direct vs iframe
| Feature | Direct Integration (/direct) | iframe Integration (/embed) |
|---|---|---|
| Resizing | โ Automatic | โ Fixed size or complex JS |
| Mobile UX | โ Perfect | โ ๏ธ Problematic |
| CORS Issues | โ None | โ ๏ธ Possible |
| Loading Speed | โ Fast | โ ๏ธ Slower |
| Customization | โ Full control | โ ๏ธ Limited |
| Animations | โ Smooth | โ ๏ธ Choppy |
| Use Case | โ Recommended for all | โ ๏ธ Legacy only |