> ## 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.

# React Component

> Embed the ThunderPhone voice widget in a React application

The `ThunderPhoneWidget` component renders a glassmorphic call bar with built-in controls for muting, ending the call, and displaying connection status. It is the fastest way to add voice AI to a React app.

## Installation

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

## Basic Usage

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

function App() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
    />
  )
}
```

<Warning>
  You **must** import the CSS file for the widget to render correctly. Without it, the widget will be unstyled.
</Warning>

***

## Props

The component accepts the following props via `ThunderPhoneWidgetProps`:

| Prop             | Type                                                           | Required | Default                                  | Description                                                                                                                                                         |
| ---------------- | -------------------------------------------------------------- | -------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `publishableKey` | `string`                                                       | Yes      | --                                       | Publishable API key (`pk_live_...`) from the Developers settings. The agent is resolved automatically from the key's widget configuration.                          |
| `theme`          | `'light' \| 'dark'`                                            | No       | `'light'`                                | Color scheme. Applies `tp--light` or `tp--dark` class to the widget root.                                                                                           |
| `primaryColor`   | `string`                                                       | No       | `'#000000'` (light) / `'#ffffff'` (dark) | CSS color string used as the accent color (call button, waveform, active indicators).                                                                               |
| `title`          | `string`                                                       | No       | `'Voice assistant'`                      | Text displayed in the widget bar.                                                                                                                                   |
| `position`       | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | No       | `'bottom-right'`                         | Fixed viewport position for the widget.                                                                                                                             |
| `apiBase`        | `string`                                                       | No       | `'https://api.thunderphone.com/v1'`      | API base URL override.                                                                                                                                              |
| `language`       | `string`                                                       | No       | --                                       | Per-session language override -- a language code or locale such as `en`, `es`, or `fr-FR`. When unset, the agent's configured language applies.                     |
| `voice`          | `string`                                                       | No       | --                                       | Per-session voice override -- a voice name such as `maria`. When unset, the agent's configured voice applies.                                                       |
| `context`        | `string`                                                       | No       | --                                       | Per-session factual page or site context passed to the agent (for example, details of the page the visitor is viewing). Truncated server-side to 12,000 characters. |
| `onConnect`      | `() => void`                                                   | No       | --                                       | Called when the voice session successfully connects.                                                                                                                |
| `onDisconnect`   | `() => void`                                                   | No       | --                                       | Called when the session ends.                                                                                                                                       |
| `onError`        | `(error) => void`                                              | No       | --                                       | Called on errors. The `error` object has `error` (code) and `message` fields.                                                                                       |
| `className`      | `string`                                                       | No       | --                                       | Additional CSS class name applied to the widget container.                                                                                                          |
| `ringtone`       | `boolean \| string`                                            | No       | `false`                                  | Play a ringtone while connecting. `true` for the default ringtone, or a URL string for custom audio.                                                                |

***

## Examples

### Dark Theme with Custom Color

```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"
      title="Talk to our AI"
    />
  )
}
```

### Custom Position

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

function App() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      position="bottom-left"
    />
  )
}
```

### Per-Session Language, Voice, and Context

The `language`, `voice`, and `context` props are forwarded to the session request (`POST /widget/session`) when a call starts, overriding the agent's configured defaults for that session:

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

function PricingPageWidget() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      language="es"
      voice="maria"
      context="Page: Pricing. Plans: Starter $29/mo, Pro $99/mo. Annual billing saves 20%."
    />
  )
}
```

Use `context` to give the agent factual knowledge about the page the visitor is on -- product details, pricing, or page-specific FAQs. It is truncated server-side to 12,000 characters.

### With Event Callbacks

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

function SupportWidget() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      onConnect={() => {
        console.log('Voice session connected')
        analytics.track('widget_call_started')
      }}
      onDisconnect={() => {
        console.log('Voice session ended')
        analytics.track('widget_call_ended')
      }}
      onError={(error) => {
        console.error(`Widget error: ${error.error} - ${error.message}`)
      }}
    />
  )
}
```

### With Custom Styling

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

function BrandedWidget() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      primaryColor="#4a90d9"
      className="my-custom-widget"
    />
  )
}
```

```css theme={null}
.my-custom-widget .tp-button--end {
  background-color: #e74c3c;
}
```

See the [Styling guide](/widget/styling) for all available CSS classes and custom properties.

### With Ringtone

Play a phone-ringing sound while the connection is being established:

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

function PhoneWidget() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      ringtone={true}
    />
  )
}
```

Use a custom ringtone by passing an audio file URL:

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  ringtone="https://example.com/my-ringtone.mp3"
/>
```

The ringtone loops while the widget is in the `connecting` state and fades out smoothly when the agent connects.

### With Custom API Base

<Tip>
  You only need to set `apiBase` if you are using a self-hosted or proxy API endpoint. The default points to `https://api.thunderphone.com/v1`.
</Tip>

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  apiBase="https://your-proxy.example.com/v1"
/>
```

***

## Error Handling

When the `onError` callback fires, it receives an error object with two fields:

| Field     | Type     | Description                      |
| --------- | -------- | -------------------------------- |
| `error`   | `string` | Machine-readable error code      |
| `message` | `string` | Human-readable error description |

Common error codes include domain not allowed, agent not found, and invalid API key.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Headless Hook" icon="code" href="/widget/headless-hook">
    Need full control over the UI? Use the `useThunderPhone` hook instead.
  </Card>

  <Card title="Styling" icon="palette" href="/widget/styling">
    Customize colors, sizes, and layout with CSS custom properties.
  </Card>
</CardGroup>
