---
title: "CDN / Etichetă de script"
description: "Adăugați widgetul vocal ThunderPhone pe orice site web fără un bundler"
---

Versiunea CDN include React intern, astfel încât puteți utiliza widgetul pe site-uri statice, WordPress, Webflow sau pe orice pagină în care puteți adăuga HTML. Nu sunt necesare npm, un bundler sau un framework.

## URL-uri 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>
  URL-urile `latest` sunt generate de generatorul de fragmente de încorporare din tabloul de bord. Sunt stocate în cache timp de 5 minute și preiau automat versiunile stabile noi. Căile fixate `/widget/vX.Y.Z/` sunt imuabile și stocate în cache pe termen lung -- dacă fixați o versiune, potriviți-o cu versiunea npm `@thunderphone/widget` pentru care dezvoltați.
</Tip>

---

## Utilizare de bază

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

Widgetul se montează în elementul-țintă și se afișează ca o **bară cu poziție fixă într-un colț al ferestrei de vizualizare** (implicit `bottom-right`, controlat prin opțiunea `position`). Elementul de montare este doar rădăcina React -- poziția sa în pagină nu afectează locul în care apare widgetul.

---

## Opțiuni de montare

`ThunderPhone.mount()` acceptă aceleași opțiuni ca componenta React, plus proprietatea `element`:

| Opțiune | Tip | Obligatoriu | Implicit | Descriere |
|--------|------|----------|---------|-------------|
| `element` | `string \| HTMLElement` | Da | -- | Selector CSS (de exemplu, `'#thunderphone'`) sau o referință la un element DOM. |
| `publishableKey` | `string` | Da | -- | Cheie API publicabilă (`pk_live_...`). Agentul este determinat automat din configurația widgetului cheii. |
| `theme` | `'light' \| 'dark'` | Nu | `'light'` | Schemă de culori. |
| `primaryColor` | `string` | Nu | `'#000000'` (deschis) / `'#ffffff'` (închis) | Șir de culoare CSS utilizat ca culoare de accent. |
| `title` | `string` | Nu | `'Voice assistant'` | Text afișat în bara widgetului. |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | Nu | `'bottom-right'` | Poziție fixă în fereastra de vizualizare. |
| `apiBase` | `string` | Nu | `'https://api.thunderphone.com/v1'` | Suprascrierea URL-ului de bază al API-ului. |
| `language` | `string` | Nu | -- | Suprascrierea limbii pentru fiecare sesiune -- un cod de limbă sau o setare regională, precum `en`, `es` sau `fr-FR`. Dacă nu este setată, se aplică limba configurată a agentului. Necesită `language` în [suprascrierile pentru browser](/ro/guides/embed-web-widget) ale cheii. |
| `voice` | `string` | Nu | -- | Suprascrierea vocii pentru fiecare sesiune -- un nume de voce, precum `maria`. Dacă nu este setată, se aplică vocea configurată a agentului. Necesită `voice` în [suprascrierile pentru browser](/ro/guides/embed-web-widget) ale cheii. |
| `context` | `string` | Nu | -- | Context factual al paginii sau site-ului pentru fiecare sesiune, transmis agentului. Este trunchiat pe server la 12.000 de caractere. Necesită `context` în [suprascrierile pentru browser](/ro/guides/embed-web-widget) ale cheii. |
| `onConnect` | `() => void` | Nu | -- | Apelată când sesiunea vocală se conectează. |
| `onDisconnect` | `() => void` | Nu | -- | Apelată când sesiunea se încheie. |
| `onError` | `(error) => void` | Nu | -- | Apelată la erori. Eroarea are câmpurile `error` (cod) și `message`. |
| `ringtone` | `boolean \| string` | Nu | `false` | Redați un ton de apel în timpul conectării. `true` pentru tonul de apel implicit sau un șir URL pentru audio personalizat. |

---

## Curățare

`ThunderPhone.mount()` returnează o instanță de widget cu metode de curățare:

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

Atât `unmount()`, cât și `destroy()` au același efect -- deconectează orice sesiune vocală activă și elimină widgetul din DOM. Folosiți varianta care se potrivește mai bine în codul dumneavoastră.

<Note>
  Curățați întotdeauna widgetul când navigați în afara aplicațiilor cu o singură pagină sau când elementul care îl conține este eliminat. Astfel vă asigurați că sesiunile vocale active sunt deconectate corect.
</Note>

---

## Exemple

### Temă întunecată cu culoare personalizată

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

### Poziție personalizată

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

### Cu callbackuri de evenimente

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

### Cu ton de apel

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

### Utilizarea unei referințe la un element 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>
```

### Integrare WordPress / CMS

Adăugați acest cod într-un bloc HTML personalizat sau în subsolul temei dumneavoastră:

```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>
  Elementul `<div>` poate fi plasat oriunde -- este doar punctul de montare. Widgetul propriu-zis se afișează ca o suprapunere fixă într-un colț al ferestrei de vizualizare (stabilit prin opțiunea `position`) și nu urmează fluxul conținutului din jur.
</Tip>

---

## Depanare

<AccordionGroup>
  <Accordion title="Widgetul nu apare">
    Asigurați-vă că sunt încărcate atât fișierele CSS, cât și cele JS. Verificați consola browserului pentru erori de rețea. Verificați că elementul țintă există în DOM înainte de a apela `ThunderPhone.mount()`.
  </Accordion>

  <Accordion title="ThunderPhone nu este definit">
    Scriptul nu s-a încărcat încă. Asigurați-vă că eticheta `<script>` pentru `widget.js` apare înainte de apelul de montare sau includeți apelul de montare într-un listener `DOMContentLoaded`.
  </Accordion>

  <Accordion title="Eroare: domeniu nepermis">
    Adăugați domeniul dumneavoastră la domeniile permise ale widgetului, pe pagina **Widgeturi web** din [app.thunderphone.com](https://app.thunderphone.com). `localhost` nu este permis automat în producție; adăugați-l în listă pentru a testa local.
  </Accordion>
</AccordionGroup>

---

## Pașii următori

<CardGroup cols={2}>
  <Card title="Stilizare" icon="palette" href="/ro/widget/styling">
    Personalizați aspectul widgetului cu proprietăți CSS personalizate.
  </Card>
  <Card title="Componentă React" icon="react" href="/ro/widget/react">
    Folosiți React? Integrarea componentei este mai simplă.
  </Card>
</CardGroup>
