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

# Thành phần React

> Nhúng tiện ích giọng nói ThunderPhone vào ứng dụng React

Component `ThunderPhoneWidget` hiển thị thanh cuộc gọi hiệu ứng glassmorphism với các nút điều khiển tích hợp để tắt tiếng, kết thúc cuộc gọi và hiển thị trạng thái kết nối. Đây là cách nhanh nhất để thêm AI giọng nói vào ứng dụng React.

## Cài đặt

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

## Cách dùng cơ bản

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

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

<Warning>
  Bạn **phải** import tệp CSS để widget hiển thị đúng. Nếu không, widget sẽ không có kiểu dáng.
</Warning>

***

## Thuộc tính

Component chấp nhận các thuộc tính sau thông qua `ThunderPhoneWidgetProps`:

| Thuộc tính       | Kiểu                                                           | Bắt buộc | Mặc định                               | Mô tả                                                                                                                                                                                         |
| ---------------- | -------------------------------------------------------------- | -------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `publishableKey` | `string`                                                       | Có       | --                                     | Khóa API có thể công khai (`pk_live_...`) trong phần cài đặt Nhà phát triển. Tác nhân AI được xác định tự động từ cấu hình widget của khóa.                                                   |
| `theme`          | `'light' \| 'dark'`                                            | Không    | `'light'`                              | Bảng màu. Áp dụng class `tp--light` hoặc `tp--dark` cho phần tử gốc của widget.                                                                                                               |
| `primaryColor`   | `string`                                                       | Không    | `'#000000'` (sáng) / `'#ffffff'` (tối) | Chuỗi màu CSS được dùng làm màu nhấn (nút gọi, dạng sóng, chỉ báo đang hoạt động).                                                                                                            |
| `title`          | `string`                                                       | Không    | `'Voice assistant'`                    | Văn bản hiển thị trên thanh widget.                                                                                                                                                           |
| `position`       | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | Không    | `'bottom-right'`                       | Vị trí cố định trong khung nhìn cho widget.                                                                                                                                                   |
| `apiBase`        | `string`                                                       | Không    | `'https://api.thunderphone.com/v1'`    | Ghi đè URL cơ sở API.                                                                                                                                                                         |
| `language`       | `string`                                                       | Không    | --                                     | Ghi đè ngôn ngữ theo phiên -- mã ngôn ngữ hoặc locale như `en`, `es` hoặc `fr-FR`. Khi không được đặt, ngôn ngữ đã cấu hình của tác nhân AI sẽ được áp dụng.                                  |
| `voice`          | `string`                                                       | Không    | --                                     | Ghi đè giọng nói theo phiên -- tên giọng nói như `maria`. Khi không được đặt, giọng nói đã cấu hình của tác nhân AI sẽ được áp dụng.                                                          |
| `context`        | `string`                                                       | Không    | --                                     | Ngữ cảnh thực tế của trang hoặc website theo phiên được truyền cho tác nhân AI (ví dụ: thông tin chi tiết về trang mà khách truy cập đang xem). Được cắt bớt ở phía máy chủ còn 12.000 ký tự. |
| `onConnect`      | `() => void`                                                   | Không    | --                                     | Được gọi khi phiên giọng nói kết nối thành công.                                                                                                                                              |
| `onDisconnect`   | `() => void`                                                   | Không    | --                                     | Được gọi khi phiên kết thúc.                                                                                                                                                                  |
| `onError`        | `(error) => void`                                              | Không    | --                                     | Được gọi khi xảy ra lỗi. Đối tượng `error` có các trường `error` (mã) và `message`.                                                                                                           |
| `className`      | `string`                                                       | Không    | --                                     | Tên class CSS bổ sung được áp dụng cho vùng chứa widget.                                                                                                                                      |
| `ringtone`       | `boolean \| string`                                            | Không    | `false`                                | Phát nhạc chuông trong khi kết nối. Dùng `true` cho nhạc chuông mặc định hoặc chuỗi URL cho âm thanh tùy chỉnh.                                                                               |

***

## Ví dụ

### Giao diện tối với màu tùy chỉnh

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

### Vị trí tùy chỉnh

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

### Ngôn ngữ, giọng nói và ngữ cảnh theo từng phiên

Các prop `language`, `voice` và `context` được chuyển tiếp đến yêu cầu phiên (`POST /widget/session`) khi cuộc gọi bắt đầu, ghi đè các giá trị mặc định đã cấu hình của tác nhân AI cho phiên đó:

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

Dùng `context` để cung cấp cho tác nhân AI kiến thức thực tế về trang mà khách truy cập đang xem -- chi tiết sản phẩm, giá hoặc câu hỏi thường gặp dành riêng cho trang. Giá trị này được cắt ngắn ở phía máy chủ còn 12.000 ký tự.

### Với callback sự kiện

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

### Với kiểu dáng tùy chỉnh

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

Xem [hướng dẫn kiểu dáng](/vi/widget/styling) để biết tất cả lớp CSS và thuộc tính tùy chỉnh có sẵn.

### Với nhạc chuông

Phát âm thanh chuông điện thoại trong khi thiết lập kết nối:

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

Dùng nhạc chuông tùy chỉnh bằng cách truyền URL của tệp âm thanh:

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

Nhạc chuông lặp lại khi widget ở trạng thái `connecting` và mờ dần một cách mượt mà khi tác nhân AI kết nối.

### Với API Base tùy chỉnh

<Tip>
  Bạn chỉ cần đặt `apiBase` nếu đang dùng điểm cuối API tự lưu trữ hoặc proxy. Giá trị mặc định trỏ đến `https://api.thunderphone.com/v1`.
</Tip>

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

***

## Xử lý lỗi

Khi callback `onError` được gọi, callback này nhận một đối tượng lỗi có hai trường:

| Trường    | Loại     | Mô tả                             |
| --------- | -------- | --------------------------------- |
| `error`   | `string` | Mã lỗi mà máy có thể đọc          |
| `message` | `string` | Mô tả lỗi mà con người có thể đọc |

Các mã lỗi phổ biến gồm tên miền không được phép, không tìm thấy tác nhân AI và khóa API không hợp lệ.

***

## Bước tiếp theo

<CardGroup cols={2}>
  <Card title="Hook không giao diện" icon="code" href="/vi/widget/headless-hook">
    Cần toàn quyền kiểm soát UI? Hãy dùng hook `useThunderPhone`.
  </Card>

  <Card title="Tạo kiểu" icon="palette" href="/vi/widget/styling">
    Tùy chỉnh màu sắc, kích thước và bố cục bằng thuộc tính tùy chỉnh CSS.
  </Card>
</CardGroup>
