> ## Documentation Index
> Fetch the complete documentation index at: https://docs.talkifai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# TalkifAI Widget Integration Guide

> Complete guide to integrating the TalkifAI chat widget on your website — supports both text chat and voice conversations.

## 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**](/platform/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**](/platform/create-agent) and copy your **Agent ID**
   * Navigate to the agent you want to embed
   * Copy the Agent ID (UUID format)

<Info>
  **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
</Info>

### Step 2: Add to Your Website

Add this code before `</body>`:

```html theme={null}
<!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

| Parameter   | Type   | Description                  | Example                                |
| ----------- | ------ | ---------------------------- | -------------------------------------- |
| `apiUrl`    | string | TalkifAI Chat API base URL   | `https://api.talkifai.dev/v1/chat`     |
| `widgetKey` | string | Domain-locked widget API key | `tk_widget_abc123...`                  |
| `agentId`   | string | UUID of the agent to use     | `5b710eca-ee67-4c3a-aeb6-8b541f451b40` |

### Optional Theme Parameters

| Parameter            | Type   | Default   | Description                  |
| -------------------- | ------ | --------- | ---------------------------- |
| `theme.primaryColor` | string | `#544AA8` | Primary brand color (purple) |
| `theme.primaryDark`  | string | `#312D69` | Darker shade for gradients   |

### Example Configuration

```javascript theme={null}
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__`:

```html theme={null}
<!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)

```tsx theme={null}
// 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)

```tsx theme={null}
// 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

```html theme={null}
<!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>`):

```php theme={null}
<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>`):

```liquid theme={null}
<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

| Feature                 | Description                                              |
| ----------------------- | -------------------------------------------------------- |
| **SSE Streaming**       | Real-time text streaming as AI generates responses       |
| **Voice Input**         | Tap mic button to speak — converts to text automatically |
| **Voice Output**        | Enable TTS to hear responses spoken aloud                |
| **Typing Indicator**    | Animated dots while AI is generating                     |
| **Message History**     | Scrollable conversation history                          |
| **Session Persistence** | Conversation survives page refresh (until tab close)     |

### 3. Voice Mode Features

| Feature                 | Description                                             |
| ----------------------- | ------------------------------------------------------- |
| **LiveKit WebRTC**      | Professional-grade voice quality with echo cancellation |
| **Audio Visualization** | Real-time frequency bars show when agent is speaking    |
| **Mic Mute**            | Tap mic icon to mute/unmute yourself                    |
| **Connection Status**   | Shows "Connecting...", "Connected", "Agent speaking..." |
| **Auto-Reconnect**      | Attempts to reconnect on connection loss                |

### 4. Responsive Design

| Screen Size              | Widget Width            | Widget Height                         |
| ------------------------ | ----------------------- | ------------------------------------- |
| Mobile (less than 768px) | 300px                   | 350px (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__`**

```javascript theme={null}
window.__TALKIFAI__ = {
  // ... other config
  theme: {
    primaryColor: '#0066cc',   // Your brand color
    primaryDark: '#004c99',    // Darker shade
  },
};
```

**Method 2: Via `data-*` attributes**

```html theme={null}
<script
  src="https://talkifai.dev/widget.js"
  data-primary-color="#0066cc"
  data-primary-dark="#004c99"
></script>
```

***

## Environment Variables

### Frontend (Next.js)

```env theme={null}
# .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 theme={null}
# .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 Type       | Prefix               | Usage                       | Security                  |
| -------------- | -------------------- | --------------------------- | ------------------------- |
| **Widget Key** | `tk_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:**

```javascript theme={null}
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:**

```javascript theme={null}
// 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:**

```javascript theme={null}
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:**

```javascript theme={null}
// 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__`**

```javascript theme={null}
window.__TALKIFAI__ = {
  // ... other config
  theme: {
    primaryColor: '#0066cc',   // Your brand color
    primaryDark: '#004c99',    // Darker shade
  },
};
```

**Method 2: Via `data-*` attributes**

```html theme={null}
<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:

```javascript theme={null}
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:

```html theme={null}
<link rel="preload" href="https://talkifai.dev/widget.js" as="script" />
```

***

## Browser Support

| Browser          | Version | Text Mode | Voice Mode |
| ---------------- | ------- | --------- | ---------- |
| Chrome           | 90+     | ✅         | ✅          |
| Firefox          | 88+     | ✅         | ✅          |
| Safari           | 14+     | ✅         | ✅          |
| Edge             | 90+     | ✅         | ✅          |
| Opera            | 76+     | ✅         | ✅          |
| Samsung Internet | 14+     | ✅         | ✅          |

**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):**

```javascript theme={null}
// 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):**

```html theme={null}
<!-- 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:**

```javascript theme={null}
window.__TALKIFAI__ = {
  widgetKey: "tk_live_..." // ❌ Server key exposed!
}
```

✅ **Correct:**

```javascript theme={null}
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:

```javascript theme={null}
// 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

***

## Related Documentation

* [Chat API Reference](/api-reference/chat) — REST API for custom integrations
* [Create a Text Agent](/platform/create-agent) — Set up your first agent
* [Conversation Memory](/platform/memory) — Enable long-term memory
* [Custom Functions](/guides/custom-functions) — Add API integrations

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Your Agent" icon="robot">
    Set up the agent you want to embed in the widget.
  </Card>

  <Card title="Get Widget Key" icon="key">
    Generate a domain-locked widget key in Studio.
  </Card>

  <Card title="Customize Widget" icon="palette">
    Learn how to customize colors and positioning.
  </Card>

  <Card title="View Analytics" icon="chart">
    Track widget usage and performance.
  </Card>
</CardGroup>

***

## Support

**Issues?** Contact TalkifAI support:

* Email: [support@talkifai.dev](mailto:support@talkifai.dev)
* Documentation: [https://docs.talkifai.dev](https://docs.talkifai.dev)
* Status: [https://status.talkifai.dev](https://status.talkifai.dev)
