Skip to main content

Overview

The TalkifAI Widget is a production-ready, dual-mode chatbot widget that provides:
  • Text Chat: Real-time SSE-streamed text conversations with AI agents
  • Voice Chat: LiveKit WebRTC-based voice conversations
  • Shadow DOM Isolation: No CSS bleeding from host page
  • Responsive Design: Mobile-first (300px → 800px width)
  • Voice Input/Output: Web Speech API for STT/TTS in text mode
  • Audio Visualization: Real-time frequency analysis for voice mode
Best for:
  • Customer support chatbots
  • Voice AI demos
  • Internal agent testing
  • Website live chat replacement

Quick Start

Step 1: Get Your Credentials

  1. Go to TalkifAI Studio → Organization → API Keys
  2. In the “Generate New Key” section, configure your widget key: a. Enter Key Name
    • Example: “Website Chat”, “Production Widget”, “Support Widget”
    • Max 50 characters
    b. Select Key Type
    • Click “Widget Key” (not “Secret Key”)
    • Widget Keys are browser-safe and domain-locked
    c. Add Allowed Domains (required for Widget Keys)
    • Enter comma-separated domains: mysite.com, staging.mysite.com
    • localhost is automatically allowed for development
    • Subdomains are automatically covered
    d. Click “Generate API Key”
  3. Copy the widget key immediately — it will only be shown once
    • Starts with tk_widget_ prefix
    • Store in password manager or environment variables
  4. Go to Agents and copy your Agent ID
    • Navigate to the agent you want to embed
    • Copy the Agent ID (UUID format)
Widget Key Features:
  • ✅ Safe to expose in browser/frontend code
  • ✅ Domain-locked (CORS restricted to your allowed domains)
  • localhost always allowed for development
  • ✅ Can be revoked without affecting other keys

Step 2: Add to Your Website

Add this code before </body>:
<!DOCTYPE html>
<html>
<head>
  <!-- 1. Configure widget BEFORE loading widget.js -->
  <script id="talkifai-config">
    window.__TALKIFAI__ = {
      apiUrl: "https://api.talkifai.dev/v1/chat",
      widgetKey: "tk_widget_your_key_here",
      agentId: "your-agent-id-here",
      theme: {
        primaryColor: '#544AA8',  // Default purple
        primaryDark: '#312D69',   // Default dark purple
      },
    };
  </script>
  
  <!-- 2. Load widget script -->
  <script src="https://talkifai.dev/widget.js" defer></script>
</head>
<body>
  <!-- Widget automatically renders -->
</body>
</html>
That’s it! The widget will appear as a floating button at bottom-right.

Configuration Options

Required Parameters

ParameterTypeDescriptionExample
apiUrlstringTalkifAI Chat API base URLhttps://api.talkifai.dev/v1/chat
widgetKeystringDomain-locked widget API keytk_widget_abc123...
agentIdstringUUID of the agent to use5b710eca-ee67-4c3a-aeb6-8b541f451b40

Optional Theme Parameters

ParameterTypeDefaultDescription
theme.primaryColorstring#544AA8Primary brand color (purple)
theme.primaryDarkstring#312D69Darker shade for gradients

Example Configuration

window.__TALKIFAI__ = {
  apiUrl: "https://api.talkifai.dev/v1/chat",
  widgetKey: "tk_widget_your_key_here",
  agentId: "5b710eca-ee67-4c3a-aeb6-8b541f451b40",
  theme: {
    primaryColor: '#0066cc',  // Blue brand color
    primaryDark: '#004c99',   // Darker blue
  },
};

Alternative Embed Method: Data Attributes

For plain HTML sites, you can use data-* attributes instead of window.__TALKIFAI__:
<!DOCTYPE html>
<html>
<head>
  <title>My Website with TalkifAI Widget</title>
</head>
<body>
  <!-- Widget with data attributes -->
  <script 
    src="https://talkifai.dev/widget.js" 
    data-api-url="https://api.talkifai.dev/v1/chat"
    data-widget-key="tk_widget_your_key"
    data-agent-id="your-agent-id"
    data-primary-color="#544AA8"
    data-primary-dark="#312D69"
    defer
  ></script>
</body>
</html>
Data Attributes:
  • data-api-url — API endpoint (required)
  • data-widget-key — Widget API key (required)
  • data-agent-id — Agent ID (required)
  • data-primary-color — Primary color (optional, default: #544AA8)
  • data-primary-dark — Dark primary color (optional, default: #312D69)
Note: If both window.__TALKIFAI__ and data-* attributes are provided, data-* attributes take precedence.

Framework Integrations

Next.js (App Router)

// app/layout.tsx
import Script from 'next/script'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* 1. Inject config before widget loads */}
        <Script id="talkifai-config" strategy="beforeInteractive">
          {`
            window.__TALKIFAI__ = {
              apiUrl: "${process.env.NEXT_PUBLIC_TALKIFAI_API_URL || ''}",
              widgetKey: "${process.env.NEXT_PUBLIC_TALKIFAI_WIDGET_KEY || ''}",
              agentId: "${process.env.NEXT_PUBLIC_TALKIFAI_AGENT_ID || ''}",
              theme: {
                primaryColor: '#544AA8',  // Default purple
                primaryDark: '#312D69',   // Default dark purple
              },
            };
          `}
        </Script>
        
        {/* 2. Load widget after page is interactive */}
        <Script src="https://talkifai.dev/widget.js" strategy="afterInteractive" />
        
        {children}
      </body>
    </html>
  )
}

React (Vite, CRA)

// App.tsx
import { useEffect } from 'react'

export default function App() {
  useEffect(() => {
    // Inject config
    const script = document.createElement('script')
    script.id = 'talkifai-config'
    script.textContent = `
      window.__TALKIFAI__ = {
        apiUrl: "https://api.talkifai.dev/v1/chat",
        widgetKey: "tk_widget_your_key",
        agentId: "your-agent-id",
        theme: {
          primaryColor: '#544AA8',  // Default purple
          primaryDark: '#312D69',   // Default dark purple
        },
      };
    `
    document.head.appendChild(script)

    // Load widget
    const widgetScript = document.createElement('script')
    widgetScript.src = 'https://talkifai.dev/widget.js'
    widgetScript.defer = true
    document.body.appendChild(widgetScript)

    return () => {
      // Cleanup on unmount
      document.head.removeChild(script)
      document.body.removeChild(widgetScript)
    }
  }, [])

  return <div>{/* Your app */}</div>
}

Plain HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>My Website with TalkifAI Widget</title>
  
  <!-- Widget config -->
  <script id="talkifai-config">
    window.__TALKIFAI__ = {
      apiUrl: "https://api.talkifai.dev/v1/chat",
      widgetKey: "tk_widget_your_key",
      agentId: "your-agent-id",
    };
  </script>
  
  <!-- Widget script -->
  <script src="https://talkifai.dev/widget.js" defer></script>
</head>
<body>
  <h1>Welcome to My Website</h1>
  <p>Chat widget will appear at bottom-right corner.</p>
</body>
</html>

WordPress

Add to Appearance → Theme Editor → footer.php (before </body>):
<script id="talkifai-config">
  window.__TALKIFAI__ = {
    apiUrl: "https://api.talkifai.dev/v1/chat",
    widgetKey: "<?php echo get_option('talkifai_widget_key'); ?>",
    agentId: "<?php echo get_option('talkifai_agent_id'); ?>",
  };
</script>
<script src="https://talkifai.dev/widget.js" defer></script>

Shopify

Add to Online Store → Themes → Edit code → layout/theme.liquid (before </body>):
<script id="talkifai-config">
  window.__TALKIFAI__ = {
    apiUrl: "https://api.talkifai.dev/v1/chat",
    widgetKey: "{{ settings.talkifai_widget_key }}",
    agentId: "{{ settings.talkifai_agent_id }}",
  };
</script>
<script src="https://talkifai.dev/widget.js" defer></script>

Widget Features

1. Dual-Mode Interface

Users can switch between:
  • Text Mode: Traditional chat interface with typing
  • Voice Mode: Real-time voice conversation (like a phone call)
Mode Switcher: Located in header — tap “Text” or “Voice” to switch.

2. Text Mode Features

FeatureDescription
SSE StreamingReal-time text streaming as AI generates responses
Voice InputTap mic button to speak — converts to text automatically
Voice OutputEnable TTS to hear responses spoken aloud
Typing IndicatorAnimated dots while AI is generating
Message HistoryScrollable conversation history
Session PersistenceConversation survives page refresh (until tab close)

3. Voice Mode Features

FeatureDescription
LiveKit WebRTCProfessional-grade voice quality with echo cancellation
Audio VisualizationReal-time frequency bars show when agent is speaking
Mic MuteTap mic icon to mute/unmute yourself
Connection StatusShows “Connecting…”, “Connected”, “Agent speaking…”
Auto-ReconnectAttempts to reconnect on connection loss

4. Responsive Design

Screen SizeWidget WidthWidget Height
Mobile (less than 768px)300px350px (collapsed) to 400px (expanded)
Desktop (768px and up)470px to 800px (zoomed)470px
Expand Button: Tap the expand icon in header to zoom on desktop.

Customization

Changing Colors

The widget uses a purple gradient theme by default (#544AA8#312D69). To customize: Method 1: Via window.__TALKIFAI__
window.__TALKIFAI__ = {
  // ... other config
  theme: {
    primaryColor: '#0066cc',   // Your brand color
    primaryDark: '#004c99',    // Darker shade
  },
};
Method 2: Via data-* attributes
<script
  src="https://talkifai.dev/widget.js"
  data-primary-color="#0066cc"
  data-primary-dark="#004c99"
></script>

Environment Variables

Frontend (Next.js)

# .env.local
NEXT_PUBLIC_TALKIFAI_API_URL=https://api.talkifai.dev/v1/chat
NEXT_PUBLIC_TALKIFAI_WIDGET_KEY=tk_widget_your_key_here
NEXT_PUBLIC_TALKIFAI_AGENT_ID=5b710eca-ee67-4c3a-aeb6-8b541f451b40

Backend (API Proxy Routes)

# .env.local
TALKIFAI_API_URL=https://api.talkifai.dev/v1/chat
TALKIFAI_API_KEY=tk_live_your_server_key_here
TALKIFAI_AGENT_ID=5b710eca-ee67-4c3a-aeb6-8b541f451b40
Important:
  • NEXT_PUBLIC_* variables are exposed to browser (safe for widget key)
  • TALKIFAI_API_KEY is server-side only (never expose tk_live_* keys)

Security Considerations

Widget Key vs Secret Key

Key TypePrefixUsageSecurity
Widget Keytk_widget_...Browser-safe, domain-locked✅ Safe for frontend
Secret Key(no prefix, 64-char)Server-side only❌ Never expose to browser
Best Practice: Always use a Widget Key for frontend integrations. Widget Key Features:
  • ✅ Domain-locked (only work on your allowed domains)
  • ✅ Rate-limited for security
  • ✅ Cannot create other API keys
  • ✅ Can be revoked without affecting other keys
  • localhost always allowed for development

Creating a Widget Key in TalkifAI Studio

Steps:
  1. Go to Organization → API Keys
  2. In “Generate New Key” section:
    • Enter Key Name (e.g., “Website Widget”)
    • Select “Widget Key” (not “Secret Key”)
    • Add Allowed Domains (comma-separated)
  3. Click “Generate API Key”
  4. Copy immediately — shown only once
Allowed Domains Format:
mysite.com, staging.mysite.com, app.mysite.com
Domain Rules:
  • Subdomains automatically covered (mysite.com includes *.mysite.com)
  • localhost always allowed for development
  • Multiple domains: separate with commas
  • Protocol (https://) optional

CORS Configuration

Widget keys are automatically configured with CORS restrictions based on your allowed domains: Example Configuration:
Allowed Origins:
- https://mysite.com
- https://staging.mysite.com
- http://localhost:* (development)
To Update Domains:
  1. Go to Organization → API Keys
  2. Find your widget key in “Your API Keys” section
  3. Click to edit (or revoke and create new)
  4. Update allowed domains list
Multiple domains: Add each domain separately during creation.

Session Token Security

Session tokens (session_token) returned from /sessions:
  • Valid for 24 hours
  • Tied to specific conversation_id
  • Cannot be used to create new sessions
  • Automatically invalidated when session ends
Safe to store in:
  • sessionStorage (cleared on tab close)
  • Memory (React state/ref)
Do NOT store in:
  • localStorage (persists indefinitely)
  • Cookies without HttpOnly flag

Troubleshooting

Widget Not Appearing

Check:
  1. Config script loaded before widget.js
  2. window.__TALKIFAI__ is defined (check browser console)
  3. No JavaScript errors in console
  4. Widget script URL is correct
Debug:
console.log(window.__TALKIFAI__)
// Should output: { apiUrl, widgetKey, agentId, theme }

“Failed to Create Session”

Causes:
  • Invalid widget key
  • Agent ID not found
  • CORS origin not configured
  • Insufficient credits
Check:
// In browser console
fetch('https://api.talkifai.dev/v1/chat/sessions', {
  method: 'POST',
  headers: {
    'X-API-Key': window.__TALKIFAI__.widgetKey,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ agent_id: window.__TALKIFAI__.agentId })
})
.then(r => r.json())
.then(console.log)
.catch(console.error)

Voice Mode Not Working

Check:
  1. Microphone permissions granted
  2. LiveKit URL is reachable
  3. Agent supports voice (Pipeline or Realtime architecture)
  4. Browser supports WebRTC (Chrome, Firefox, Safari, Edge)
Debug:
navigator.mediaDevices.getUserMedia({ audio: true })
  .then(() => console.log('Mic permissions OK'))
  .catch(err => console.error('Mic permissions denied:', err))

Text Streaming Not Working

Check:
  1. API returns Content-Type: text/event-stream
  2. SSE parser handles all event types
  3. Network tab shows streaming response
Debug:
// Test SSE endpoint directly
const eventSource = new EventSource(
  'https://api.talkifai.dev/v1/chat/sessions/{id}/messages',
  { headers: { 'Authorization': 'Bearer {token}' } }
)
eventSource.onmessage = (e) => console.log('SSE:', e.data)

Customization

Changing Colors

The widget uses a purple gradient theme by default (#544AA8#312D69). To customize: Method 1: Via window.__TALKIFAI__
window.__TALKIFAI__ = {
  // ... other config
  theme: {
    primaryColor: '#0066cc',   // Your brand color
    primaryDark: '#004c99',    // Darker shade
  },
};
Method 2: Via data-* attributes
<script
  src="https://talkifai.dev/widget.js"
  data-primary-color="#0066cc"
  data-primary-dark="#004c99"
></script>

Performance Optimization

Lazy Loading

Load widget only when user interacts:
let widgetLoaded = false

function loadWidget() {
  if (widgetLoaded) return
  widgetLoaded = true
  
  // Inject config
  const config = document.createElement('script')
  config.id = 'talkifai-config'
  config.textContent = `
    window.__TALKIFAI__ = {
      apiUrl: "https://api.talkifai.dev/v1/chat",
      widgetKey: "tk_widget_key",
      agentId: "agent_id",
    };
  `
  document.head.appendChild(config)
  
  // Load widget
  const widget = document.createElement('script')
  widget.src = 'https://talkifai.dev/widget.js'
  widget.defer = true
  document.body.appendChild(widget)
}

// Load on first user interaction
document.addEventListener('click', loadWidget, { once: true })

Preloading

Preload widget script for faster load:
<link rel="preload" href="https://talkifai.dev/widget.js" as="script" />

Browser Support

BrowserVersionText ModeVoice Mode
Chrome90+
Firefox88+
Safari14+
Edge90+
Opera76+
Samsung Internet14+
Voice Mode Requirements:
  • WebRTC support
  • Microphone permissions
  • Audio playback
Text Mode Requirements:
  • Fetch API
  • SSE (Server-Sent Events)
  • Modern JavaScript (ES6+)

Migration Guide

From Chat API to Widget

If you already have a custom chat integration: Before (Custom Implementation):
// Your custom chat code
const session = await fetch('/api/chat/session', { ... })
const response = await fetch(`/api/chat/messages`, { ... })
// ... SSE parsing, UI rendering, etc.
After (Widget):
<!-- Just add widget -->
<script src="https://talkifai.dev/widget.js"></script>
Benefits:
  • ✅ No custom UI code needed
  • ✅ Built-in voice mode
  • ✅ Automatic session management
  • ✅ Responsive design included
  • ✅ Shadow DOM isolation

From Other Chat Widgets

From Intercom/Drift/Zendesk:
  1. Remove old widget script
  2. Add TalkifAI config + widget
  3. Update agent in TalkifAI Studio
  4. Test on staging first
Migration Checklist:
  • Remove old widget code
  • Create TalkifAI agent (import conversation history if needed)
  • Configure widget key with CORS
  • Test text mode
  • Test voice mode
  • Verify analytics tracking
  • Deploy to production

Best Practices

1. Always Use Widget Keys

Wrong:
window.__TALKIFAI__ = {
  widgetKey: "tk_live_..." // ❌ Server key exposed!
}
Correct:
window.__TALKIFAI__ = {
  widgetKey: "tk_widget_..." // ✅ Browser-safe
}

2. Configure CORS Properly

Add only trusted domains to widget key CORS allowlist:
  • Production domain
  • Staging domain (for testing)
  • Localhost (for development)

3. Handle Session Cleanup

Widget automatically ends sessions on close, but you can explicitly end:
// Before page unload
window.addEventListener('beforeunload', () => {
  if (sessionRef.current) {
    fetch(`/sessions/${sessionRef.current.conversation_id}/end`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${sessionRef.current.session_token}` },
      keepalive: true,
    })
  }
})

4. Test on Multiple Devices

Test widget on:
  • Desktop (Chrome, Firefox, Safari, Edge)
  • Mobile (iOS Safari, Chrome Android)
  • Tablets (iPad, Android tablets)

5. Monitor Widget Performance

Track metrics:
  • Widget load time
  • Session creation time
  • Message latency
  • Voice connection success rate


Next Steps

Create Your Agent

Set up the agent you want to embed in the widget.

Get Widget Key

Generate a domain-locked widget key in Studio.

Customize Widget

Learn how to customize colors and positioning.

View Analytics

Track widget usage and performance.

Support

Issues? Contact TalkifAI support: