---
title: "Komponent React"
description: "Osadź widżet głosowy ThunderPhone w aplikacji React"
---

Komponent `ThunderPhoneWidget` renderuje szklany pasek połączenia z wbudowanymi elementami sterującymi do wyciszania, kończenia połączenia i wyświetlania stanu połączenia. To najszybszy sposób na dodanie głosowej AI do aplikacji React.

## Instalacja

```bash
npm install @thunderphone/widget
```

## Podstawowe użycie

```tsx
import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function App() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
    />
  )
}
```

<Warning>
  Aby widżet renderował się poprawnie, **musisz** zaimportować plik CSS. Bez niego widżet nie będzie miał stylów.
</Warning>

---

## Właściwości

Komponent przyjmuje następujące właściwości przez `ThunderPhoneWidgetProps`:

| Właściwość | Typ | Wymagane | Domyślnie | Opis |
|------|------|----------|---------|-------------|
| `publishableKey` | `string` | Tak | -- | Publikowalny klucz API (`pk_live_...`) z sekcji **Widżety internetowe** w panelu. Agent jest określany automatycznie na podstawie konfiguracji widżetu klucza. |
| `theme` | `'light' \| 'dark'` | Nie | `'light'` | Schemat kolorów. Stosuje klasę `tp--light` lub `tp--dark` do głównego elementu widżetu. |
| `primaryColor` | `string` | Nie | `'#000000'` (jasny) / `'#ffffff'` (ciemny) | Ciąg koloru CSS używany jako kolor akcentu (przycisk połączenia, przebieg fali, aktywne wskaźniki). |
| `title` | `string` | Nie | `'Voice assistant'` | Tekst wyświetlany na pasku widżetu. |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | Nie | `'bottom-right'` | Stała pozycja widżetu w obszarze widoku. |
| `apiBase` | `string` | Nie | `'https://api.thunderphone.com/v1'` | Zastępuje bazowy adres URL API. |
| `language` | `string` | Nie | -- | Zastąpienie języka dla sesji — kod języka lub ustawienia regionalne, takie jak `en`, `es` lub `fr-FR`. Jeśli nie jest ustawione, używany jest język skonfigurowany dla agenta. Wymaga `language` w sekcji [nadpisania przeglądarki](/pl/guides/embed-web-widget) klucza. |
| `voice` | `string` | Nie | -- | Zastąpienie głosu dla sesji — nazwa głosu, taka jak `maria`. Jeśli nie jest ustawione, używany jest głos skonfigurowany dla agenta. Wymaga `voice` w sekcji [nadpisania przeglądarki](/pl/guides/embed-web-widget) klucza. |
| `context` | `string` | Nie | -- | Kontekst faktyczny strony lub witryny dla sesji przekazywany agentowi (na przykład szczegóły strony oglądanej przez odwiedzającego). Po stronie serwera skracany do 12 000 znaków. Wymaga `context` w sekcji [nadpisania przeglądarki](/pl/guides/embed-web-widget) klucza. |
| `onConnect` | `() => void` | Nie | -- | Wywoływane, gdy sesja głosowa zostanie pomyślnie połączona. |
| `onDisconnect` | `() => void` | Nie | -- | Wywoływane po zakończeniu sesji. |
| `onError` | `(error) => void` | Nie | -- | Wywoływane w przypadku błędów. Obiekt `error` zawiera pola `error` (kod) i `message`. |
| `className` | `string` | Nie | -- | Dodatkowa nazwa klasy CSS stosowana do kontenera widżetu. |
| `ringtone` | `boolean \| string` | Nie | `false` | Odtwarza dzwonek podczas łączenia. `true` oznacza domyślny dzwonek, a ciąg URL — niestandardowy dźwięk. |

---

## Przykłady

### Ciemny motyw z niestandardowym kolorem

```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"
    />
  )
}
```

### Niestandardowa pozycja

```tsx
import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function App() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      position="bottom-left"
    />
  )
}
```

### Język, głos i kontekst dla sesji

Właściwości `language`, `voice` i `context` są przekazywane do żądania sesji (`POST /widget/session`) podczas rozpoczęcia połączenia, zastępując domyślne ustawienia agenta skonfigurowane dla tej sesji. Włącz każdą używaną właściwość w sekcji **Nadpisania przeglądarki** widżetu w panelu (lub w `allowed_overrides` klucza). Nowe widżety nie akceptują żadnych nadpisań, a żądanie sesji zawierające wyłączone nadpisanie kończy się błędem `400 override_not_allowed`; zobacz [Nadpisania przeglądarki](/pl/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%."
    />
  )
}
```

Użyj `context`, aby przekazać agentowi faktyczną wiedzę o stronie, na której znajduje się odwiedzający — szczegóły produktu, ceny lub najczęstsze pytania dotyczące konkretnej strony. Agent traktuje je jako zawartość strony, a nie instrukcje. Po stronie serwera jest ono skracane do 12 000 znaków.

### Z wywołaniami zwrotnymi zdarzeń

```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}`)
      }}
    />
  )
}
```

### Z niestandardowym stylem

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

Zobacz [przewodnik po stylach](/pl/widget/styling), aby poznać wszystkie dostępne klasy CSS i niestandardowe właściwości.

### Z dzwonkiem

Odtwarzaj dźwięk dzwoniącego telefonu podczas nawiązywania połączenia:

```tsx
import { ThunderPhoneWidget } from '@thunderphone/widget'
import '@thunderphone/widget/style.css'

function PhoneWidget() {
  return (
    <ThunderPhoneWidget
      publishableKey="pk_live_your_publishable_key"
      ringtone={true}
    />
  )
}
```

Użyj niestandardowego dzwonka, przekazując adres URL pliku audio:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  ringtone="https://example.com/my-ringtone.mp3"
/>
```

Dzwonek jest odtwarzany w pętli, gdy widżet jest w stanie `connecting`, i płynnie cichnie, gdy agent się połączy.

### Z niestandardową bazą API

<Tip>
  Właściwość `apiBase` musisz ustawić tylko wtedy, gdy używasz samodzielnie hostowanego lub pośredniczącego punktu końcowego API. Domyślnie wskazuje ona na `https://api.thunderphone.com/v1`.
</Tip>

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  apiBase="https://your-proxy.example.com/v1"
/>
```

---

## Obsługa błędów

Gdy wywołanie zwrotne `onError` zostanie uruchomione, otrzymuje obiekt błędu z dwoma polami:

| Pole | Typ | Opis |
|-------|------|-------------|
| `error` | `string` | Kod błędu czytelny dla maszyny |
| `message` | `string` | Opis błędu czytelny dla człowieka |

Typowe kody błędów obejmują niedozwoloną domenę, nieznalezionego agenta i nieprawidłowy klucz API.

---

## Kolejne kroki

<CardGroup cols={2}>
  <Card title="Hook bez interfejsu" icon="code" href="/pl/widget/headless-hook">
    Potrzebujesz pełnej kontroli nad interfejsem użytkownika? Zamiast tego użyj hooka `useThunderPhone`.
  </Card>
  <Card title="Stylizacja" icon="palette" href="/pl/widget/styling">
    Dostosuj kolory, rozmiary i układ za pomocą niestandardowych właściwości CSS.
  </Card>
</CardGroup>
