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

# Komponen React

> Sematkan widget suara ThunderPhone dalam aplikasi React

Komponen `ThunderPhoneWidget` merender bilah panggilan bergaya glassmorphism dengan kontrol bawaan untuk membisukan, mengakhiri panggilan, dan menampilkan status koneksi. Ini adalah cara tercepat untuk menambahkan agen suara AI ke aplikasi React.

## Instalasi

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

## Penggunaan Dasar

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

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

<Warning>
  Anda **harus** mengimpor file CSS agar widget dirender dengan benar. Tanpanya, widget tidak akan memiliki gaya.
</Warning>

***

## Properti

Komponen menerima properti berikut melalui `ThunderPhoneWidgetProps`:

| Properti         | Tipe                                                           | Wajib | Default                                    | Deskripsi                                                                                                                                                                      |
| ---------------- | -------------------------------------------------------------- | ----- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `publishableKey` | `string`                                                       | Ya    | --                                         | Kunci API yang dapat dipublikasikan (`pk_live_...`) dari pengaturan Developers. Agen ditentukan secara otomatis dari konfigurasi widget kunci tersebut.                        |
| `theme`          | `'light' \| 'dark'`                                            | Tidak | `'light'`                                  | Skema warna. Menerapkan kelas `tp--light` atau `tp--dark` ke root widget.                                                                                                      |
| `primaryColor`   | `string`                                                       | Tidak | `'#000000'` (terang) / `'#ffffff'` (gelap) | String warna CSS yang digunakan sebagai warna aksen (tombol panggilan, waveform, indikator aktif).                                                                             |
| `title`          | `string`                                                       | Tidak | `'Voice assistant'`                        | Teks yang ditampilkan di bilah widget.                                                                                                                                         |
| `position`       | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | Tidak | `'bottom-right'`                           | Posisi viewport tetap untuk widget.                                                                                                                                            |
| `apiBase`        | `string`                                                       | Tidak | `'https://api.thunderphone.com/v1'`        | Override URL basis API.                                                                                                                                                        |
| `language`       | `string`                                                       | Tidak | --                                         | Override bahasa per sesi -- kode bahasa atau lokal seperti `en`, `es`, atau `fr-FR`. Jika tidak ditetapkan, bahasa yang dikonfigurasi untuk agen akan digunakan.               |
| `voice`          | `string`                                                       | Tidak | --                                         | Override suara per sesi -- nama suara seperti `maria`. Jika tidak ditetapkan, suara yang dikonfigurasi untuk agen akan digunakan.                                              |
| `context`        | `string`                                                       | Tidak | --                                         | Konteks faktual halaman atau situs per sesi yang diteruskan ke agen (misalnya, detail halaman yang sedang dilihat pengunjung). Dipotong di sisi server hingga 12.000 karakter. |
| `onConnect`      | `() => void`                                                   | Tidak | --                                         | Dipanggil saat sesi suara berhasil terhubung.                                                                                                                                  |
| `onDisconnect`   | `() => void`                                                   | Tidak | --                                         | Dipanggil saat sesi berakhir.                                                                                                                                                  |
| `onError`        | `(error) => void`                                              | Tidak | --                                         | Dipanggil saat terjadi error. Objek `error` memiliki field `error` (kode) dan `message`.                                                                                       |
| `className`      | `string`                                                       | Tidak | --                                         | Nama kelas CSS tambahan yang diterapkan ke container widget.                                                                                                                   |
| `ringtone`       | `boolean \| string`                                            | Tidak | `false`                                    | Putar nada dering saat menghubungkan. `true` untuk nada dering default, atau string URL untuk audio kustom.                                                                    |

***

## Contoh

### Tema Gelap dengan Warna Kustom

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

### Posisi Kustom

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

### Bahasa, Suara, dan Konteks per Sesi

Prop `language`, `voice`, dan `context` diteruskan ke permintaan sesi (`POST /widget/session`) saat panggilan dimulai, sehingga menimpa pengaturan default agen untuk sesi tersebut:

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

Gunakan `context` untuk memberikan agen pengetahuan faktual tentang halaman yang sedang dilihat pengunjung -- detail produk, harga, atau FAQ khusus halaman. Nilainya dipotong di sisi server hingga 12.000 karakter.

### Dengan Callback Peristiwa

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

### Dengan Gaya Kustom

```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;
}
```

Lihat [panduan Styling](/id/widget/styling) untuk semua kelas CSS dan properti kustom yang tersedia.

### Dengan Nada Dering

Putar suara dering telepon saat koneksi sedang dibuat:

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

Gunakan nada dering kustom dengan meneruskan URL file audio:

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

Nada dering berulang saat widget berada dalam status `connecting` dan memudar dengan mulus saat agen terhubung.

### Dengan Basis API Kustom

<Tip>
  Anda hanya perlu menetapkan `apiBase` jika menggunakan endpoint API yang di-host sendiri atau diproksikan. Nilai default mengarah ke `https://api.thunderphone.com/v1`.
</Tip>

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

***

## Penanganan Error

Saat callback `onError` dipanggil, callback tersebut menerima objek error dengan dua bidang:

| Bidang    | Tipe     | Deskripsi                                 |
| --------- | -------- | ----------------------------------------- |
| `error`   | `string` | Kode error yang dapat dibaca mesin        |
| `message` | `string` | Deskripsi error yang dapat dibaca manusia |

Kode error umum mencakup domain tidak diizinkan, agen tidak ditemukan, dan kunci API tidak valid.

***

## Langkah Selanjutnya

<CardGroup cols={2}>
  <Card title="Hook Headless" icon="code" href="/id/widget/headless-hook">
    Butuh kontrol penuh atas UI? Gunakan hook `useThunderPhone` sebagai gantinya.
  </Card>

  <Card title="Penataan Gaya" icon="palette" href="/id/widget/styling">
    Sesuaikan warna, ukuran, dan tata letak dengan properti kustom CSS.
  </Card>
</CardGroup>
