> ## 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 元件

> 在 React 應用程式中嵌入 ThunderPhone 語音小工具

`ThunderPhoneWidget` 元件會呈現具有玻璃擬態風格的通話列，內建靜音、結束通話及顯示連線狀態的控制項。這是在 React 應用程式中加入語音人工智慧功能最快的方法。

## 安裝

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

## 基本用法

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

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

<Warning>
  你**必須**匯入 CSS 檔案，元件才能正確呈現。否則，元件將不會套用任何樣式。
</Warning>

***

## Props

此元件可透過 `ThunderPhoneWidgetProps` 接受以下 props：

| Prop             | 類型                                                             | 必填 | 預設值                                 | 說明                                                                    |
| ---------------- | -------------------------------------------------------------- | -- | ----------------------------------- | --------------------------------------------------------------------- |
| `publishableKey` | `string`                                                       | 是  | --                                  | 開發人員設定中的可公開 API 金鑰（`pk_live_...`）。系統會根據該金鑰的元件設定自動解析智慧體。               |
| `theme`          | `'light' \| 'dark'`                                            | 否  | `'light'`                           | 色彩配置。將 `tp--light` 或 `tp--dark` 類別套用至元件根元素。                           |
| `primaryColor`   | `string`                                                       | 否  | `'#000000'`（淺色）／`'#ffffff'`（深色）     | 作為強調色使用的 CSS 色彩字串（通話按鈕、波形、啟用中的指示器）。                                   |
| `title`          | `string`                                                       | 否  | `'Voice assistant'`                 | 顯示於元件列中的文字。                                                           |
| `position`       | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | 否  | `'bottom-right'`                    | 元件在檢視區中的固定位置。                                                         |
| `apiBase`        | `string`                                                       | 否  | `'https://api.thunderphone.com/v1'` | 覆寫 API 基底 URL。                                                        |
| `language`       | `string`                                                       | 否  | --                                  | 每個工作階段的語言覆寫設定——可使用語言代碼或地區設定，例如 `en`、`es` 或 `fr-FR`。未設定時，會套用智慧體所設定的語言。 |
| `voice`          | `string`                                                       | 否  | --                                  | 每個工作階段的語音覆寫設定——可使用語音名稱，例如 `maria`。未設定時，會套用智慧體所設定的語音。                  |
| `context`        | `string`                                                       | 否  | --                                  | 傳遞給智慧體的每個工作階段事實性頁面或網站脈絡（例如訪客正在瀏覽頁面的詳細資訊）。伺服器端會截斷至 12,000 個字元。         |
| `onConnect`      | `() => void`                                                   | 否  | --                                  | 語音工作階段成功連線時呼叫。                                                        |
| `onDisconnect`   | `() => void`                                                   | 否  | --                                  | 工作階段結束時呼叫。                                                            |
| `onError`        | `(error) => void`                                              | 否  | --                                  | 發生錯誤時呼叫。`error` 物件包含 `error`（代碼）和 `message` 欄位。                       |
| `className`      | `string`                                                       | 否  | --                                  | 套用至元件容器的額外 CSS 類別名稱。                                                  |
| `ringtone`       | `boolean \| string`                                            | 否  | `false`                             | 連線時播放鈴聲。`true` 代表使用預設鈴聲，或使用 URL 字串指定自訂音訊。                             |

***

## 範例

### 深色主題搭配自訂顏色

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

### 自訂位置

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

### 每個工作階段的語言、語音和情境

通話開始時，`language`、`voice` 和 `context` 屬性會傳送至工作階段請求（`POST /widget/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%."
    />
  )
}
```

使用 `context` 向智慧體提供訪客目前所在頁面的事實資訊——產品詳細資料、價格或頁面專屬常見問題。伺服器端會將其截斷為 12,000 個字元。

### 搭配事件回呼

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

### 搭配自訂樣式

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

請參閱[樣式指南](/zh-Hant/widget/styling)，瞭解所有可用的 CSS 類別和自訂屬性。

### 搭配鈴聲

建立連線時播放電話響鈴聲：

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

傳入音訊檔案 URL 以使用自訂鈴聲：

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

當小工具處於 `connecting` 狀態時，鈴聲會循環播放；智慧體連線後，鈴聲會平順淡出。

### 搭配自訂 API 基底

<Tip>
  只有在使用自行託管或代理 API 端點時，才需要設定 `apiBase`。預設值指向 `https://api.thunderphone.com/v1`。
</Tip>

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

***

## 錯誤處理

觸發 `onError` 回呼時，會收到包含兩個欄位的錯誤物件：

| 欄位        | 類型       | 說明        |
| --------- | -------- | --------- |
| `error`   | `string` | 機器可讀的錯誤代碼 |
| `message` | `string` | 人類可讀的錯誤說明 |

常見錯誤代碼包括不允許的網域、找不到智慧體，以及無效的 API 金鑰。

***

## 後續步驟

<CardGroup cols={2}>
  <Card title="無介面 Hook" icon="code" href="/zh-Hant/widget/headless-hook">
    需要完全掌控 UI？改用 `useThunderPhone` Hook。
  </Card>

  <Card title="樣式設定" icon="palette" href="/zh-Hant/widget/styling">
    使用 CSS 自訂屬性自訂顏色、尺寸與版面配置。
  </Card>
</CardGroup>
