---
title: "คอมโพเนนต์ React"
description: "ฝังวิดเจ็ตเสียง ThunderPhone ในแอปพลิเคชัน React"
---

คอมโพเนนต์ `ThunderPhoneWidget` แสดงแถบการโทรแบบกลาสมอร์ฟิกพร้อมตัวควบคุมในตัวสำหรับปิดเสียง วางสาย และแสดงสถานะการเชื่อมต่อ เป็นวิธีที่รวดเร็วที่สุดในการเพิ่ม AI เสียงลงในแอป React

## การติดตั้ง

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

## การใช้งานพื้นฐาน

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

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

<Warning>
  คุณ**ต้อง**นำเข้าไฟล์ CSS เพื่อให้วิดเจ็ตแสดงผลอย่างถูกต้อง หากไม่มีไฟล์นี้ วิดเจ็ตจะไม่มีการจัดรูปแบบ
</Warning>

---

## Props

คอมโพเนนต์รับ props ต่อไปนี้ผ่าน `ThunderPhoneWidgetProps`:

| 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'` | แทนที่ URL ฐานของ API |
| `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
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
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
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
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
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;
}
```

ดู[คู่มือการจัดรูปแบบ](/th/widget/styling)สำหรับคลาส CSS และคุณสมบัติแบบกำหนดเองที่ใช้งานได้ทั้งหมด

### พร้อมเสียงเรียกเข้า

เล่นเสียงโทรศัพท์ดังระหว่างกำลังสร้างการเชื่อมต่อ:

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

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

ใช้เสียงเรียกเข้าแบบกำหนดเองโดยส่ง URL ของไฟล์เสียง:

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

เสียงเรียกเข้าจะเล่นวนซ้ำขณะที่วิดเจ็ตอยู่ในสถานะ `connecting` และจะค่อย ๆ เบาลงอย่างนุ่มนวลเมื่อเอเจนต์เชื่อมต่อ

### พร้อมฐาน API แบบกำหนดเอง

<Tip>
  คุณต้องตั้งค่า `apiBase` เฉพาะเมื่อใช้ปลายทาง API ที่โฮสต์เองหรือผ่านพร็อกซีเท่านั้น ค่าเริ่มต้นชี้ไปที่ `https://api.thunderphone.com/v1`
</Tip>

```tsx
<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 แบบ Headless" icon="code" href="/th/widget/headless-hook">
    ต้องการควบคุม UI อย่างเต็มรูปแบบหรือไม่ ใช้ hook `useThunderPhone` แทน
  </Card>
  <Card title="การจัดสไตล์" icon="palette" href="/th/widget/styling">
    ปรับแต่งสี ขนาด และเลย์เอาต์ด้วยคุณสมบัติแบบกำหนดเองของ CSS
  </Card>
</CardGroup>
