---
title: "React 컴포넌트"
description: "React 애플리케이션에 ThunderPhone 음성 위젯을 임베드합니다"
---

`ThunderPhoneWidget` 컴포넌트는 음소거, 통화 종료, 연결 상태 표시를 위한 기본 제공 컨트롤이 포함된 글래스모피즘 통화 바를 렌더링합니다. React 앱에 음성 AI를 추가하는 가장 빠른 방법입니다.

## 설치

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

---

## 속성

컴포넌트는 `ThunderPhoneWidgetProps`를 통해 다음 속성을 받습니다.

| 속성 | 유형 | 필수 | 기본값 | 설명 |
|------|------|------|---------|-------------|
| `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`과 같은 언어 코드 또는 로캘을 지정합니다. 설정하지 않으면 에이전트에 구성된 언어가 적용됩니다. 키의 [브라우저 재정의](/ko/guides/embed-web-widget)에서 `language`를 설정해야 합니다. |
| `voice` | `string` | 아니요 | -- | 세션별 음성 재정의입니다. `maria`와 같은 음성 이름을 지정합니다. 설정하지 않으면 에이전트에 구성된 음성이 적용됩니다. 키의 [브라우저 재정의](/ko/guides/embed-web-widget)에서 `voice`를 설정해야 합니다. |
| `context` | `string` | 아니요 | -- | 에이전트에 전달되는 세션별 사실 기반 페이지 또는 사이트 컨텍스트입니다(예: 방문자가 보고 있는 페이지의 세부 정보). 서버 측에서 12,000자로 잘립니다. 키의 [브라우저 재정의](/ko/guides/embed-web-widget)에서 `context`를 설정해야 합니다. |
| `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` prop이 세션 요청(`POST /widget/session`)으로 전달되어 해당 세션에 대해 에이전트에 구성된 기본값을 재정의합니다. 사용하는 각 prop은 대시보드에서 위젯의 **브라우저 재정의** 아래에서 활성화하거나 키의 `allowed_overrides`에서 활성화합니다. 새 위젯은 어떤 재정의도 허용하지 않으며, 비활성화된 재정의를 포함한 세션 요청은 `400 override_not_allowed` 오류로 실패합니다. 자세한 내용은 [브라우저 재정의](/ko/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%."
    />
  )
}
```

`context`를 사용하여 방문자가 보고 있는 페이지에 관한 사실 정보를 에이전트에 제공합니다. 예를 들어 제품 세부 정보, 가격 또는 페이지별 FAQ를 제공할 수 있습니다. 에이전트는 이를 지시가 아닌 페이지 콘텐츠로 처리합니다. 서버 측에서 최대 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;
}
```

사용 가능한 모든 CSS 클래스와 사용자 지정 속성은 [스타일링 가이드](/ko/widget/styling)를 참조하십시오.

### 벨소리 사용

연결이 설정되는 동안 전화 벨소리를 재생합니다.

```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 Base 사용

<Tip>
  자체 호스팅 또는 프록시 API 엔드포인트를 사용하는 경우에만 `apiBase`를 설정하면 됩니다. 기본값은 `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" icon="code" href="/ko/widget/headless-hook">
    UI를 완전히 제어해야 하나요? 대신 `useThunderPhone` Hook을 사용하세요.
  </Card>
  <Card title="스타일링" icon="palette" href="/ko/widget/styling">
    CSS 사용자 지정 속성으로 색상, 크기, 레이아웃을 맞춤 설정하세요.
  </Card>
</CardGroup>
