---
title: "CDN／Script Tag"
description: "無需使用打包工具，即可將 ThunderPhone 語音小工具加入任何網站"
---

CDN 版本已內置 React，因此你可在靜態網站、WordPress、Webflow，或任何可加入 HTML 的頁面上使用小工具。無需 npm、打包工具或框架。

## CDN 網址

<CodeGroup>
```html Latest (recommended)
<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
<!-- 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` 網址由控制台的嵌入程式碼產生器建立。它們會快取 5 分鐘，並自動套用新的穩定版本。固定版本的 `/widget/vX.Y.Z/` 路徑不可變更，並會長期快取——如使用固定版本，請確保版本與你開發時使用的 `@thunderphone/widget` npm 發布版本一致。
</Tip>

---

## 基本用法

```html
<!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'` (light) / `'#ffffff'` (dark) | 用作強調色的 CSS 色彩字串。 |
| `title` | `string` | 否 | `'Voice assistant'` | 顯示於小工具列的文字。 |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | 否 | `'bottom-right'` | 固定於檢視區的位置。 |
| `apiBase` | `string` | 否 | `'https://api.thunderphone.com/v1'` | 覆寫 API 基礎網址。 |
| `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
<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
<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
<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
<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
<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
<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
<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="Widget 未有顯示">
    確保 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="/yue/widget/styling">
    使用 CSS 自訂屬性自訂 Widget 外觀。
  </Card>
  <Card title="React 元件" icon="react" href="/yue/widget/react">
    使用 React？元件整合方式更簡單。
  </Card>
</CardGroup>
