Documentation Index
Fetch the complete documentation index at: https://docs.voltai.ai/llms.txt
Use this file to discover all available pages before exploring further.
Here are some common ways to use the Voltai Widget.
Basic setup
The simplest integration—just load and go:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Site</title>
</head>
<body>
<h1>Welcome</h1>
<script src="https://cdn.voltai.ai/widget@latest/voltai-widget.js"></script>
<script>
Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true
});
</script>
</body>
</html>
Custom branded theme
Match the widget to your brand colors:
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true,
title: 'Acme Support',
colors: {
// Primary brand color
bgButtonPrimary: '#FF6B00',
textPrimaryBrand: '#FF6B00',
iconPrimaryBrand: '#FF6B00',
// Text on primary buttons
textPrimaryInverse: '#FFFFFF',
iconInverse: '#FFFFFF'
}
});
Open the widget from your own button instead of (or in addition to) the floating button:
<button id="help-btn" class="help-button">
Need help?
</button>
<script>
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true
});
document.getElementById('help-btn').onclick = () => {
voltai.open();
};
</script>
Contextual help
Send a pre-filled question based on where the user is on your site:
<button onclick="askAboutPricing()">Questions about pricing?</button>
<button onclick="askAboutIntegration()">Need integration help?</button>
<script>
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true
});
async function askAboutPricing() {
voltai.open();
await voltai.sendChat('What are your pricing plans?', {
topics: ['Sales', 'Pricing']
});
}
async function askAboutIntegration() {
voltai.open();
await voltai.sendChat('How do I integrate with my existing systems?', {
topics: ['Technical', 'Integration']
});
}
</script>
Event tracking
Track widget usage for analytics:
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true,
onReady: () => {
console.log('Widget mounted');
},
onAuthReady: ({ isLoggedIn, isGuest }) => {
console.log('Auth initialized', { isLoggedIn, isGuest });
},
onOpen: () => {
// Track in your analytics
gtag('event', 'widget_open', {
event_category: 'Support'
});
},
onClose: () => {
gtag('event', 'widget_close', {
event_category: 'Support'
});
}
});
// Track messages
voltai.on('chat:send', (payload) => {
gtag('event', 'chat_message', {
event_category: 'Support',
event_label: payload.topics?.join(', ')
});
});
Sync host auth before opening
Use onAuthReady when you want to make an auth decision before the widget is opened:
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true,
onAuthReady: async ({ isLoggedIn }) => {
if (!isLoggedIn) {
await voltai.login();
}
}
});
If the visitor later opens the widget without a session and guest access is enabled, the normal captcha and guest verification flow still happens inside the widget.
Use authClickEvents.mode when you want the widget to emit auth click events but let your app decide what to do next.
observe keeps the normal widget auth flow
intercept stops the normal widget auth flow so your page can handle auth itself
const voltai = Voltai.load({
apiKey: 'your-api-key',
authClickEvents: {
mode: 'intercept'
}
});
voltai.on('auth:sign-in-click', () => {
openYourLoginModal();
});
voltai.on('auth:sign-out-click', () => {
signOutFromYourApp();
});
voltai.login() and voltai.logout() still work normally in intercept mode.
Create a custom control panel:
<div class="widget-controls">
<button id="open-btn">Open Chat</button>
<button id="close-btn">Close Chat</button>
<button id="toggle-btn">Toggle Chat</button>
</div>
<script>
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true,
title: 'Help Center'
});
document.getElementById('open-btn').onclick = () => voltai.open();
document.getElementById('close-btn').onclick = () => voltai.close();
document.getElementById('toggle-btn').onclick = () => voltai.toggle();
</script>
Let users choose a topic before starting a chat:
<form id="chat-form">
<input type="text" id="question" placeholder="Your question..." required />
<select id="topic">
<option value="General">General</option>
<option value="Technical">Technical Support</option>
<option value="Billing">Billing</option>
<option value="Sales">Sales</option>
</select>
<button type="submit">Ask</button>
</form>
<script>
const voltai = Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true
});
document.getElementById('chat-form').onsubmit = async (e) => {
e.preventDefault();
const question = document.getElementById('question').value;
const topicName = document.getElementById('topic').value;
voltai.open();
await voltai.sendChat(question, {
topics: [topicName]
});
// Clear form
document.getElementById('question').value = '';
};
</script>
React integration
Using the widget in a React application:
import { useEffect, useRef } from 'react';
function App() {
const voltaiRef = useRef(null);
useEffect(() => {
// Initialize on mount
voltaiRef.current = window.Voltai.load({
apiKey: 'your-api-key',
enableGuestUser: true,
onReady: () => console.log('Widget ready')
});
// Cleanup on unmount
return () => {
voltaiRef.current?.destroy();
};
}, []);
const openChat = () => {
voltaiRef.current?.open();
};
return (
<div>
<h1>My React App</h1>
<button onClick={openChat}>Get Help</button>
</div>
);
}
Make sure the widget script is loaded before your React app mounts. You can add it to your index.html or load it dynamically.
Multi-organization authenticated users
If your users can access more than one organization, set defaultOrgName so the widget prefers the org you expect:
const voltai = Voltai.load({
apiKey: 'your-api-key',
authConnection: 'EXAMPLE',
defaultOrgName: 'Acme',
title: 'Acme Support'
});
This is useful when a single user account belongs to multiple orgs and you want the widget to open in the same org context as the rest of your site.