Skip to main content
The ThunderPhoneWidget component renders a ready-to-use call button 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

npm install @thunderphone/widget

Basic Usage

import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function App() {
  return (
    <ThunderPhoneWidget
      apiKey="pk_live_your_publishable_key"
      agentId={123}
    />
  )
}
You must import the CSS file for the widget to render correctly. Without it, the widget will be unstyled.

Props

The component accepts the following props via ThunderPhoneWidgetProps:
PropTypeRequiredDescription
apiKeystringYesPublishable API key (pk_live_...) from the Developers settings
agentIdnumberYesID of the agent to connect to (must have Embeddable Widget enabled)
apiBasestringNoAPI base URL. Defaults to https://api.thunderphone.com/v1
onConnect() => voidNoCalled when the voice session successfully connects
onDisconnect() => voidNoCalled when the session ends
onError(error) => voidNoCalled on errors. The error object has error (code) and message fields
classNamestringNoAdditional CSS class name applied to the widget container
ringtoneboolean | stringNoPlay a ringtone while connecting. true for the default ringtone, or a URL string for custom audio. Disabled by default

Examples

With Event Callbacks

import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function SupportWidget() {
  return (
    <ThunderPhoneWidget
      apiKey="pk_live_your_publishable_key"
      agentId={123}
      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

import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function BrandedWidget() {
  return (
    <ThunderPhoneWidget
      apiKey="pk_live_your_publishable_key"
      agentId={123}
      className="my-custom-widget"
    />
  )
}
.my-custom-widget .tp-button--start {
  background-color: #4a90d9;
}

.my-custom-widget .tp-button--end {
  background-color: #e74c3c;
}
See the Styling guide for all available CSS classes.

With Ringtone

Play a phone-ringing sound while the connection is being established:
import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function PhoneWidget() {
  return (
    <ThunderPhoneWidget
      apiKey="pk_live_your_publishable_key"
      agentId={123}
      ringtone={true}
    />
  )
}
Use a custom ringtone by passing an audio file URL:
<ThunderPhoneWidget
  apiKey="pk_live_your_publishable_key"
  agentId={123}
  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

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.
<ThunderPhoneWidget
  apiKey="pk_live_your_publishable_key"
  agentId={123}
  apiBase="https://your-proxy.example.com/v1"
/>

Error Handling

When the onError callback fires, it receives an error object with two fields:
FieldTypeDescription
errorstringMachine-readable error code
messagestringHuman-readable error description
Common error codes include domain not allowed, agent not found, and invalid API key.

Next Steps