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

# Embeddable Voice Widget

> Add a voice AI agent to any website with a few lines of code

The ThunderPhone embeddable voice widget lets your website visitors talk to an AI agent directly from the browser. No phone call required -- users click a button and start a real-time voice conversation powered by ThunderPhone.

The widget renders as a glassmorphic bar that adapts to light and dark themes, with customizable accent colors and positioning. It is distributed as the `@thunderphone/widget` npm package and is also available via CDN for non-bundler environments.

<Frame>
  <img src="https://mintcdn.com/thunderphone/4XhPaCl4RGfyS7_M/images/widget-showcase.png?fit=max&auto=format&n=4XhPaCl4RGfyS7_M&q=85&s=17fea4fe853f3548b9b2628c9d4c4fc0" alt="ThunderPhone widget in light and dark themes with various accent colors" width="1200" height="800" data-path="images/widget-showcase.png" />
</Frame>

## Prerequisites

Before embedding the widget, complete these three steps in the [ThunderPhone Dashboard](https://app.thunderphone.com):

<Steps>
  <Step title="Create a publishable API key">
    Go to **Developers** in the dashboard settings and create a publishable key. Publishable keys start with `pk_live_` and are safe to include in client-side code.
  </Step>

  <Step title="Configure allowed domains">
    In the same Developers settings, add the domains where the widget will be embedded. `localhost` is always allowed for development. Wildcards are supported (e.g., `*.example.com`).
  </Step>

  <Step title="Create a web widget">
    Go to **Web Widgets** in the dashboard and create a widget. Select the agent you want to expose and the publishable key to use. The agent is resolved automatically from your publishable key configuration.
  </Step>
</Steps>

<Warning>
  Publishable keys (`pk_live_...`) are **not** the same as your secret API tokens. Publishable keys are designed for client-side use and are scoped to widget sessions on your allowed domains. Never use your secret API token in client-side code.
</Warning>

***

## Quick Start

Install the package:

```bash theme={null}
npm install @thunderphone/widget
```

Drop the widget into your app:

```tsx theme={null}
import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function App() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      theme="dark"
      primaryColor="#8b5cf6"
    />
  )
}
```

That's it. Your users will see a glassmorphic call bar that connects them to your AI agent with a single click.

***

## Customization

The widget has four appearance props:

| Prop           | Default                                  | Description                                                                     |
| -------------- | ---------------------------------------- | ------------------------------------------------------------------------------- |
| `theme`        | `'light'`                                | `'light'` for white glass, `'dark'` for dark glass                              |
| `primaryColor` | `'#000000'` (light) / `'#ffffff'` (dark) | Accent color for the start button, waveform, and connecting indicator           |
| `title`        | `'Voice assistant'`                      | Text displayed in the widget                                                    |
| `position`     | `'bottom-right'`                         | Viewport corner: `'bottom-right'`, `'bottom-left'`, `'top-right'`, `'top-left'` |

<CodeGroup>
  ```tsx Light theme (default) theme={null}
  <ThunderPhoneWidget
    publishableKey="pk_live_your_publishable_key"
  />
  ```

  ```tsx Dark theme with custom color theme={null}
  <ThunderPhoneWidget
    publishableKey="pk_live_your_publishable_key"
    theme="dark"
    primaryColor="#8b5cf6"
    title="Ask our AI"
  />
  ```
</CodeGroup>

Three more props customize the session rather than the look -- all are forwarded to the session request when a call starts:

| Prop       | Description                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------- |
| `language` | Per-session language override -- a code or locale such as `en`, `es`, or `fr-FR`              |
| `voice`    | Per-session voice override -- a voice name such as `maria`                                    |
| `context`  | Factual page or site context passed to the agent (truncated server-side to 12,000 characters) |

See the [React component reference](/widget/react) for the full props table.

For a fully custom UI, use the [headless hook](/widget/headless-hook) to manage the voice session while you build your own interface. The hook exposes real-time audio levels for building audio-reactive visualizations.

***

## Integration Options

Choose the integration method that fits your stack:

<CardGroup cols={3}>
  <Card title="React Component" icon="react" href="/widget/react">
    Pre-built UI component with built-in call controls and status display. Import, pass props, done.
  </Card>

  <Card title="Headless Hook" icon="code" href="/widget/headless-hook">
    Full control over the UI. The `useThunderPhone` hook manages the voice session while you build your own interface.
  </Card>

  <Card title="CDN / Script Tag" icon="globe" href="/widget/cdn-script-tag">
    No bundler required. Load the widget via a script tag for static sites, WordPress, and other non-React environments.
  </Card>
</CardGroup>

***

## Styling

The widget ships with built-in light and dark themes controlled by the `theme` prop, and an accent color controlled by the `primaryColor` prop. For deeper customization, you can override CSS custom properties and classes. See the [Styling guide](/widget/styling) for details.

<Note>
  Need help? Contact us at [support@thunderphone.com](mailto:support@thunderphone.com)
</Note>
