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

# Create a web widget in the dashboard

> Set up a click-to-talk widget for your site from the Web Widgets page — no API calls required.

The **Web Widgets** page (`/dashboard/web-widgets`) creates and manages
the publishable keys that power ThunderPhone's embeddable voice widget.
Everything the [API version of this guide](/guides/embed-web-widget)
does with cURL, this page does with a form — plus it generates the embed
code for you.

## Create a widget

<Steps>
  <Step title="Click New widget and pick a mode">
    * **Agent mode** — the widget always runs one agent you pick from
      the dropdown. The simplest setup.
    * **Webhook mode** — on every widget session, ThunderPhone calls
      your webhook URL and your server returns the agent configuration
      for that visitor (per-page routing, logged-in users, rollouts).
      Leave the URL blank to use your organization's default webhook;
      when you enter a new URL you can also set it as the org default.
  </Step>

  <Step title="List the allowed domains">
    Publishable keys are origin-locked: at least one domain is required,
    and the widget only works on the hostnames you list. Subdomain
    wildcards like `*.example.com` are allowed (they match subdomains,
    not the bare domain); bare wildcards like `*` are rejected.
    `localhost` and `127.0.0.1` are always allowed, so local development
    works without listing them.
  </Step>

  <Step title="Name it, enable it, create it">
    The **Enable widget** toggle controls whether the key accepts
    sessions — you can create a widget disabled and flip it on at launch.
  </Step>
</Steps>

## Grab the embed code

Right after creation (or via each row's **Embed** button), an embed
dialog generates ready-to-paste code with your publishable key filled
in:

* **React** — a `<ThunderPhoneWidget />` snippet for bundler apps.
* **Script tag** — a CDN `<script>` + stylesheet pair for any site.

The dialog also previews basic appearance options — title, primary
color, corner position, and light/dark theme — and bakes your choices
into the snippet. For the full prop reference, styling hooks, and the
headless option, see the [widget SDK docs](/widget/overview).

<Note>
  Publishable keys (`pk_live_…`) are public by design — safe to ship in
  front-end code. Copy one anytime with the copy button on its row.
</Note>

## Manage widgets from the list

Each row edits in place:

* **Mode / Agent** — switch between agent and webhook mode, or repoint
  the agent, with inline selects.
* **Domains** — add or remove allowed domains as chips.
* **Enable/disable** — a switch per widget; disabled widgets stop
  accepting sessions immediately.
* **Transfer to org** — copy or move the widget to another organization
  you belong to (moving removes it here).
* **Delete** — revokes the publishable key; the widget stops working
  immediately on all domains. This can't be undone.

Widget sessions appear in [call history](/guides/review-calls) with the
same transcript, recording, and grading as phone calls.

## Next steps

<CardGroup cols={2}>
  <Card title="Widget SDK reference" icon="window-maximize" href="/widget/overview">
    React component, headless hook, and CDN script details.
  </Card>

  <Card title="Webhook-mode routing" icon="bolt" href="/guides/dynamic-call-config">
    Return per-visitor agent config from your server.
  </Card>
</CardGroup>
