---
title: "Componente de React"
description: "Incorpora el widget de voz de ThunderPhone en una aplicación de React"
---

El componente `ThunderPhoneWidget` muestra una barra de llamada con efecto de vidrio esmerilado y controles integrados para silenciar, finalizar la llamada y mostrar el estado de conexión. Es la forma más rápida de agregar IA de voz a una app de React.

## Instalación

```bash
npm install @thunderphone/widget
```

## Uso básico

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

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

<Warning>
  Debes importar el archivo CSS para que el widget se muestre correctamente. Sin él, el widget no tendrá estilos.
</Warning>

---

## Propiedades

El componente acepta las siguientes propiedades mediante `ThunderPhoneWidgetProps`:

| Propiedad | Tipo | Obligatorio | Predeterminado | Descripción |
|------|------|----------|---------|-------------|
| `publishableKey` | `string` | Sí | -- | Clave de API publicable (`pk_live_...`) de **Widgets web** en el panel. El agente se determina automáticamente a partir de la configuración del widget de la clave. |
| `theme` | `'light' \| 'dark'` | No | `'light'` | Esquema de color. Aplica la clase `tp--light` o `tp--dark` a la raíz del widget. |
| `primaryColor` | `string` | No | `'#000000'` (claro) / `'#ffffff'` (oscuro) | Cadena de color CSS usada como color de acento (botón de llamada, forma de onda, indicadores activos). |
| `title` | `string` | No | `'Voice assistant'` | Texto que se muestra en la barra del widget. |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | No | `'bottom-right'` | Posición fija del widget en la ventana gráfica. |
| `apiBase` | `string` | No | `'https://api.thunderphone.com/v1'` | Anulación de la URL base de la API. |
| `language` | `string` | No | -- | Anulación del idioma por sesión -- un código de idioma o una configuración regional, como `en`, `es` o `fr-FR`. Cuando no se establece, se aplica el idioma configurado del agente. Requiere `language` en las [anulaciones del navegador](/es/guides/embed-web-widget) de la clave. |
| `voice` | `string` | No | -- | Anulación de voz por sesión -- un nombre de voz, como `maria`. Cuando no se establece, se aplica la voz configurada del agente. Requiere `voice` en las [anulaciones del navegador](/es/guides/embed-web-widget) de la clave. |
| `context` | `string` | No | -- | Contexto factual de la página o el sitio por sesión que se pasa al agente (por ejemplo, detalles de la página que está viendo el visitante). Se trunca en el servidor a 12,000 caracteres. Requiere `context` en las [anulaciones del navegador](/es/guides/embed-web-widget) de la clave. |
| `onConnect` | `() => void` | No | -- | Se llama cuando la sesión de voz se conecta correctamente. |
| `onDisconnect` | `() => void` | No | -- | Se llama cuando finaliza la sesión. |
| `onError` | `(error) => void` | No | -- | Se llama cuando ocurren errores. El objeto `error` tiene los campos `error` (código) y `message`. |
| `className` | `string` | No | -- | Nombre de clase CSS adicional aplicado al contenedor del widget. |
| `ringtone` | `boolean \| string` | No | `false` | Reproduce un tono de llamada durante la conexión. `true` para el tono predeterminado o una cadena de URL para audio personalizado. |

---

## Ejemplos

### Tema oscuro con color personalizado

```tsx
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"
    />
  )
}
```

### Posición personalizada

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

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

### Idioma, voz y contexto por sesión

Las props `language`, `voice` y `context` se reenvían a la solicitud de sesión (`POST /widget/session`) cuando comienza una llamada, anulando los valores predeterminados configurados del agente para esa sesión. Activa cada prop que uses en **Anulaciones del navegador** para el widget en el dashboard (o en `allowed_overrides` de la clave). Los widgets nuevos no aceptan ninguna, y una solicitud de sesión que incluya una desactivada falla con `400 override_not_allowed`; consulta [Anulaciones del navegador](/es/guides/embed-web-widget).

```tsx
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%."
    />
  )
}
```

Usa `context` para proporcionar al agente conocimiento factual sobre la página en la que está el visitante: detalles del producto, precios o preguntas frecuentes específicas de la página. El agente lo trata como contenido de la página, no como instrucciones. Se trunca del lado del servidor a 12.000 caracteres.

### Con callbacks de eventos

```tsx
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}`)
      }}
    />
  )
}
```

### Con estilos personalizados

```tsx
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
.my-custom-widget .tp-button--end {
  background-color: #e74c3c;
}
```

Consulta la [guía de estilos](/es/widget/styling) para ver todas las clases de CSS y propiedades personalizadas disponibles.

### Con tono de llamada

Reproduce un sonido de teléfono sonando mientras se establece la conexión:

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

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

Usa un tono de llamada personalizado pasando la URL de un archivo de audio:

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

El tono de llamada se repite mientras el widget está en el estado `connecting` y se desvanece suavemente cuando el agente se conecta.

### Con una base de API personalizada

<Tip>
  Solo necesitas configurar `apiBase` si usas un endpoint de API autohospedado o con proxy. El valor predeterminado apunta a `https://api.thunderphone.com/v1`.
</Tip>

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

---

## Manejo de errores

Cuando se activa el callback `onError`, recibe un objeto de error con dos campos:

| Campo | Tipo | Descripción |
|-------|------|-------------|
| `error` | `string` | Código de error legible por máquinas |
| `message` | `string` | Descripción de error legible por humanos |

Los códigos de error comunes incluyen dominio no permitido, agente no encontrado y clave de API no válida.

---

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Hook headless" icon="code" href="/es/widget/headless-hook">
    ¿Necesitas control total sobre la interfaz? Usa el hook `useThunderPhone`.
  </Card>
  <Card title="Estilos" icon="palette" href="/es/widget/styling">
    Personaliza los colores, tamaños y la disposición con propiedades personalizadas de CSS.
  </Card>
</CardGroup>
