---
title: "Osadź widżet internetowy"
description: "Dodaj agenta głosowego do swojej witryny marketingowej lub wsparcia za pomocą jednego tagu skryptu — odwiedzający rozmawiają z nim bezpośrednio w przeglądarce, bez potrzeby podawania numeru telefonu."
---

Widżet internetowy zapewnia odwiedzającym Twoją witrynę rozmowę typu kliknij, aby porozmawiać
z agentem AI, przy użyciu mikrofonu przeglądarki. To osobny zestaw SDK
JavaScript / React z własnym [opisem SDK](/pl/widget/overview)
— ten przewodnik koncentruje się na konfiguracji po stronie ThunderPhone, której potrzebuje widżet.

<Note>
  Możesz zrobić to wszystko bez cURL: strona **Widżety internetowe** w panelu
  (`/dashboard/web-widgets`) tworzy widżet, ustawia jego tryb
  i agenta AI, zarządza dozwolonymi domenami oraz udostępnia fragment kodu do osadzenia.
</Note>

## Wymagania wstępne

<Steps>
  <Step title="Utwórz agenta">
    Agent, którego prompt i głos będą obsługiwać sesję widżetu. Ustaw
    `widget_enabled: true` (wartość domyślna).
  </Step>
  <Step title="Wybierz tryb routingu">
    - `mode="agent"` — jeden statyczny agent na klucz. Najprostsza opcja.
    - `mode="webhook"` — serwer wybiera agenta dla każdego odwiedzającego za pomocą
      [webhooka `web.incoming`](/pl/webhooks/call-incoming). Użyj tej opcji dla
      zalogowanych użytkowników, testów A/B lub routingu na poziomie strony.
  </Step>
  <Step title="Wymień dozwolone domeny">
    Podaj każdą nazwę hosta, która będzie osadzać widżet. Przeglądarki wysyłają
    origin strony z każdym żądaniem sesji, więc lista uniemożliwia użycie klucza,
    gdy ktoś skopiuje go na inną witrynę. To nie jest uwierzytelnianie: skrypt
    poza przeglądarką może wysłać dowolny nagłówek `Origin`. `localhost` nie jest
    automatycznie dozwolony w środowisku produkcyjnym; aby testować lokalnie
    względem produkcyjnego API, dodaj `localhost` do listy.
  </Step>
  <Step title="Wybierz nadpisania przeglądarki">
    Zdecyduj, które ustawienia sesji może wysyłać strona. Nowe klucze nie
    akceptują żadnych; zobacz [Nadpisania przeglądarki](#browser-overrides).
  </Step>
</Steps>

## Utwórz klucz publikowalny

<CodeGroup>
```bash Static agent
curl -X POST https://api.thunderphone.com/v1/publishable-key \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name":            "Marketing site (prod)",
    "mode":            "agent",
    "agent_id":        12,
    "allowed_domains": ["example.com", "*.example.com"],
    "allowed_overrides": ["context"]
  }'
```

```bash Dynamic via webhook
curl -X POST https://api.thunderphone.com/v1/publishable-key \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name":            "Support (dynamic)",
    "mode":            "webhook",
    "webhook_url":     "https://example.com/thunderphone/widget-hook",
    "allowed_domains": ["support.example.com"]
  }'
```
</CodeGroup>

Odpowiedź zawiera `key` zaczynający się od `pk_live_...`. **Klucze publikowalne
są z założenia publiczne** — można je bezpiecznie umieścić w pakiecie front-endu.
Wszystkie pola znajdziesz w [opisie kluczy publikowalnych](/api-reference/publishable-keys).

<Warning>
  `allowed_domains` musi zawierać co najmniej jeden wpis. `*.example.com`
  dopasowuje subdomeny (np. `api.example.com`), ale **nie** domenę
  bez subdomeny. Symbole wieloznaczne dla całej domeny, takie jak `*` lub `*.*`, są odrzucane.
</Warning>

## Umieść widżet na swojej stronie

Trzy opcje integracji opisano w
[dokumentacji SDK widżetu](/pl/widget/overview):

<CardGroup cols={3}>
  <Card title="Komponent React" icon="react" href="/pl/widget/react">
    `<ThunderPhoneWidget publishableKey="pk_live_..." />`.
  </Card>
  <Card title="Hook bez interfejsu" icon="circle-nodes" href="/pl/widget/headless-hook">
    `useThunderPhone()` dla niestandardowych interfejsów.
  </Card>
  <Card title="Tag skryptu CDN" icon="code" href="/pl/widget/cdn-script-tag">
    `ThunderPhone.mount({...})` dla witryn bez narzędzia do pakietowania.
  </Card>
</CardGroup>

Wszystkie trzy akceptują ten sam `publishableKey` i renderują przycisk mikrofonu
oraz element audio podczas rozmowy.

## Nadpisania przeglądarki

Widżet może wysyłać ze strony cztery ustawienia dla sesji:

| Ustawienie | Właściwość widżetu | Co zmienia |
|---------|-------------|-----------------|
| `context` | `context` | Tekst ze strony, dodawany do promptu agenta jako materiał referencyjny |
| `variables` | brak (tylko surowe `POST /v1/widget/session`) | Wartości dla symboli zastępczych `{{variable}}` w promptcie |
| `voice` | `voice` | Głos agenta w tej sesji |
| `language` | `language` | Język, w którym rozpoczyna się sesja |

Twój klucz publikowalny jest publiczny, więc każdy, kto go posiada, może wysyłać te
ustawienia, także ze skryptu podszywającego się pod Twoją domenę. Dlatego wszystkie są
domyślnie wyłączone, dopóki nie zezwolisz na nie dla klucza: zaznacz je w sekcji **Nadpisania przeglądarki** podczas tworzenia lub edytowania widżetu w panelu albo ustaw
`allowed_overrides` za pomocą
[API kluczy publikowalnych](/api-reference/publishable-keys). Zezwalaj tylko na to,
co faktycznie wysyła Twoja strona.

Żądanie sesji zawierające ustawienie, na które klucz nie zezwala, kończy się
błędem `400` i wskazuje je:

```json
{
  "error": "override_not_allowed",
  "fields": ["voice"],
  "message": "This publishable key does not allow the browser to set `voice`. ..."
}
```

Sprawdzenie ma zastosowanie w obu trybach. W trybie webhook dozwolone ustawienie jest
również przekazywane do webhooka `web.incoming` (`context` trafia jako
`website_context`). Klucze utworzone przed wprowadzeniem tego ustawienia zezwalają na wszystkie
cztery opcje, więc istniejące osadzenia nadal działają; wyłącz to, czego nie używasz.

Wartość `context` widżetu jest skracana do 12 000 znaków (około 3 400
tokenów typowego tekstu angielskiego) i wlicza się do
[dopłaty za rozmiar promptu](/pl/guides/billing-and-topups).
Agent otrzymuje instrukcję, aby traktować ją jako treść strony, a nie jako instrukcje.

## Webhooki w trybie widżetu

Gdy `mode="webhook"`, ThunderPhone wywołuje Twój `webhook_url` przy każdym
rozpoczęciu sesji z ładunkiem `web.incoming`. Zwróć konfigurację agenta AI,
którą chcesz uruchomić dla tego odwiedzającego — korzysta ona z tego samego
[schematu odpowiedzi](/pl/webhooks/call-incoming) co połączenia
telefoniczne:

```json
{
  "prompt":  "You are a VIP concierge for Jane Doe.",
  "voice":   "john",
  "product": "storm-base",
  "tools":   [ /* per-customer tools */ ]
}
```

Możesz łączyć w prompcie kontekst z własnej sesji (który klient przegląda stronę,
na której stronie się znajduje) oraz zmieniać agentów AI dla poszczególnych wdrożeń.

## Monitoruj sesje

Sesje widżetu pojawiają się w
[`GET /v1/calls`](/api-reference/calls#list-calls) z
`direction="widget"` — mają ten sam transkrypt, nagranie, ocenę i
rozliczenia co połączenia telefoniczne. Filtruj według `direction`, aby utworzyć panel
wyłącznie dla widżetu.

---

## Kolejne kroki

<CardGroup cols={2}>
  <Card title="Dokumentacja SDK widżetu" icon="window-maximize" href="/pl/widget/overview">
    Szczegóły integracji React / hook / CDN.
  </Card>
  <Card title="Dynamiczna konfiguracja dla każdego połączenia" icon="bolt" href="/pl/guides/dynamic-call-config">
    Zaimplementuj przepływ `mode="webhook"` od początku do końca.
  </Card>
  <Card title="Dokumentacja kluczy publikowalnych" icon="key" href="/api-reference/publishable-keys">
    Każde pole zasobu klucza.
  </Card>
  <Card title="API sesji mikrofonu" icon="microphone" href="/api-reference/mic-sessions">
    Pomiń widżet; steruj LiveKit bezpośrednio, aby tworzyć niestandardowe interfejsy użytkownika.
  </Card>
</CardGroup>
