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

# CDN / 스크립트 태그

> 번들러 없이 모든 웹사이트에 ThunderPhone 음성 위젯을 추가합니다

CDN 빌드는 React를 내부적으로 번들링하므로 정적 사이트, WordPress, Webflow 또는 HTML을 추가할 수 있는 모든 페이지에서 위젯을 사용할 수 있습니다. npm, 번들러, 프레임워크가 필요하지 않습니다.

## CDN URL

<CodeGroup>
  ```html Latest (recommended) theme={null}
  <link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
  <script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
  ```

  ```html Pinned version theme={null}
  <!-- Each stable release also publishes an immutable /widget/vX.Y.Z/ path
       matching the @thunderphone/widget npm version (v1.1.2 at the time of
       writing). If you pin, you own updating the URL for new releases. -->
  <link rel="stylesheet" href="https://cdn.thunderphone.com/widget/v1.1.2/style.css" />
  <script src="https://cdn.thunderphone.com/widget/v1.1.2/widget.js"></script>
  ```
</CodeGroup>

<Tip>
  `latest` URL은 대시보드의 임베드 스니펫 생성기가 만드는 URL입니다. 5분간 캐시되며 새 안정 릴리스를 자동으로 반영합니다. 고정된 `/widget/vX.Y.Z/` 경로는 변경할 수 없으며 장기간 캐시됩니다. 고정하는 경우 개발에 사용하는 `@thunderphone/widget` npm 릴리스와 버전을 일치시키십시오.
</Tip>

***

## 기본 사용법

```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
</head>
<body>

  <div id="thunderphone"></div>

  <script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
  <script>
    ThunderPhone.mount({
      element: '#thunderphone',
      publishableKey: 'pk_live_your_publishable_key',
    })
  </script>

</body>
</html>
```

위젯은 대상 요소에 마운트되며 **뷰포트 모서리에 고정 위치 바**로 렌더링됩니다(기본값은 `bottom-right`이며 `position` 옵션으로 제어됨). 마운트 요소는 React 루트일 뿐이며, 페이지 내 위치는 위젯이 표시되는 위치에 영향을 주지 않습니다.

***

## 마운트 옵션

`ThunderPhone.mount()`는 React 컴포넌트와 동일한 옵션에 `element` 속성을 추가하여 지원합니다.

| 옵션               | 유형                                                             | 필수  | 기본값                                        | 설명                                                                                       |
| ---------------- | -------------------------------------------------------------- | --- | ------------------------------------------ | ---------------------------------------------------------------------------------------- |
| `element`        | `string \| HTMLElement`                                        | 예   | --                                         | CSS 선택자(예: `'#thunderphone'`) 또는 DOM 요소 참조입니다.                                           |
| `publishableKey` | `string`                                                       | 예   | --                                         | 공개 API 키(`pk_live_...`)입니다. 키의 위젯 구성에서 에이전트가 자동으로 확인됩니다.                                 |
| `theme`          | `'light' \| 'dark'`                                            | 아니요 | `'light'`                                  | 색상 구성표입니다.                                                                               |
| `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`(코드) 및 `message` 필드가 있습니다.                                    |
| `ringtone`       | `boolean \| string`                                            | 아니요 | `false`                                    | 연결 중 벨소리를 재생합니다. 기본 벨소리에는 `true`를 사용하고, 사용자 지정 오디오에는 URL 문자열을 사용합니다.                     |

***

## 정리

`ThunderPhone.mount()`는 정리 메서드를 포함하는 위젯 인스턴스를 반환합니다.

```html theme={null}
<script>
  var widget = ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
  })

  // Later, when you want to remove the widget:
  widget.unmount()

  // Or equivalently:
  widget.destroy()
</script>
```

`unmount()`와 `destroy()`는 동일하게 작동합니다. 활성 음성 세션의 연결을 해제하고 DOM에서 위젯을 제거합니다. 코드에서 더 자연스럽게 읽히는 메서드를 사용합니다.

<Note>
  단일 페이지 애플리케이션에서 다른 페이지로 이동하거나 포함 요소가 제거될 때는 항상 위젯을 정리합니다. 이렇게 하면 활성 음성 세션의 연결이 올바르게 해제됩니다.
</Note>

***

## 예시

### 사용자 지정 색상의 다크 테마

```html theme={null}
<div id="thunderphone"></div>

<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    theme: 'dark',
    primaryColor: '#8b5cf6',
    title: 'Talk to our AI',
  })
</script>
```

### 사용자 지정 위치

```html theme={null}
<div id="thunderphone"></div>

<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    position: 'bottom-left',
  })
</script>
```

### 이벤트 콜백 사용

```html theme={null}
<div id="thunderphone"></div>

<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    onConnect: function () {
      console.log('Call started')
    },
    onDisconnect: function () {
      console.log('Call ended')
    },
    onError: function (error) {
      console.error('Widget error:', error.error, error.message)
    },
  })
</script>
```

### 벨소리 사용

```html theme={null}
<div id="thunderphone"></div>

<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    ringtone: true, // or a custom URL: 'https://example.com/ringtone.mp3'
  })
</script>
```

### DOM 요소 참조 사용

```html theme={null}
<div id="thunderphone"></div>

<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  var container = document.getElementById('thunderphone')

  ThunderPhone.mount({
    element: container,
    publishableKey: 'pk_live_your_publishable_key',
  })
</script>
```

### WordPress / CMS 통합

사용자 지정 HTML 블록 또는 테마의 푸터에 다음을 추가합니다.

```html theme={null}
<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>

<div id="thunderphone-widget"></div>
<script>
  ThunderPhone.mount({
    element: '#thunderphone-widget',
    publishableKey: 'pk_live_your_publishable_key',
  })
</script>
```

<Tip>
  `<div>`는 어디에나 배치할 수 있으며 마운트 지점일 뿐입니다. 위젯 자체는 뷰포트 모서리에 고정 오버레이로 렌더링되며(`position` 옵션으로 설정), 주변 콘텐츠의 흐름에 영향을 받지 않습니다.
</Tip>

***

## 문제 해결

<AccordionGroup>
  <Accordion title="위젯이 표시되지 않음">
    CSS 및 JS 파일이 모두 로드되었는지 확인합니다. 브라우저 콘솔에서 네트워크 오류를 확인합니다. `ThunderPhone.mount()`를 호출하기 전에 대상 요소가 DOM에 있는지 확인합니다.
  </Accordion>

  <Accordion title="ThunderPhone이 정의되지 않음">
    스크립트가 아직 로드되지 않았습니다. `widget.js`의 `<script>` 태그가 마운트 호출 전에 있는지 확인하거나, 마운트 호출을 `DOMContentLoaded` 리스너로 감쌉니다.
  </Accordion>

  <Accordion title="허용되지 않은 도메인 오류">
    [app.thunderphone.com](https://app.thunderphone.com)의 **개발자** 설정에서 허용된 도메인 목록에 도메인을 추가합니다. `localhost`는 항상 허용됩니다.
  </Accordion>
</AccordionGroup>

***

## 다음 단계

<CardGroup cols={2}>
  <Card title="스타일 지정" icon="palette" href="/ko/widget/styling">
    CSS 사용자 지정 속성으로 위젯 모양을 사용자 지정합니다.
  </Card>

  <Card title="React 컴포넌트" icon="react" href="/ko/widget/react">
    React를 사용하시나요? 컴포넌트 통합이 더 간단합니다.
  </Card>
</CardGroup>
