> ## Documentation Index
> Fetch the complete documentation index at: https://wiredesk.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# The chat bubble is not showing up

> Find why the widget is missing or its panel is empty: the tag, the tag manager, allowed domains, caching, your CSP, and the console warnings.

Work through the checks below in order. Most missing bubbles are found at the first or second step. The browser console usually tells you which one you are in, so open it first. `widget.js` writes its own messages there, each starting with `[wiredesk]`.

## Start with the install check

Open **Agents → your agent → Install**. The card at the top shows whether a real page has loaded the widget:

* **Live on …**: a page loaded it in the last 15 minutes.
* **Installed on …**: it has loaded before, but not recently.
* **Not installed yet**: no page on another site has loaded it.

Choose **Check now** to refresh, or **Watch for it** while you load your page. **Try it on a demo page** opens a test page with the snippet already on it, so you can check the agent's side without touching your site.

If the check is green but you cannot see the bubble on one page, that page is probably built from a template the tag is not in.

## 1. Is the tag on the live page?

Open the live page, not a staging or editor preview, and view its source. Search for `wiredesk.ai/widget.js`. If it is not there, the problem is upstream of WireDesk:

* The tag was added to a template this page does not use.
* The change was saved but never published.
* A page cache is still serving the old HTML. Purge it once. Caching plugins such as WP Rocket or LiteSpeed are the usual cause.

## 2. Was the tag manager container published?

Google Tag Manager keeps changes in a workspace until you publish a version. In a preview session the tag fires perfectly while the live site has nothing. This is the most common cause on sites that use a tag manager.

<Steps>
  <Step title="Check the container is published">
    A previewed tag is not a published tag. **Submit** the workspace.
  </Step>

  <Step title="Check the trigger">
    Use **All Pages**, unless you want the widget on fewer pages. A trigger that never matches behaves the same as a missing tag.
  </Step>
</Steps>

You do not need any other change for a tag manager. When a tag manager injects the script, the script finds its own tag by its `src` and reads `data-widget` from it.

## 3. Is the domain on the allowed list?

If the widget has [allowed domains](/docs/widget/allowed-domains), a site that is not on the list is refused:

* The config request answers `403` with `{"error": "this widget is not allowed on this domain", "domain": "…"}`. The launcher may still draw, in the default style, and the console shows the `could not load the widget config` warning described below.
* The conversation frame is served with a `frame-ancestors` policy that leaves out your site. When the visitor opens the panel, the browser refuses to render it, and the console reports the blocked frame.

So an unlisted domain looks like a missing style or an empty panel, not always a missing bubble. The usual case is a list that has production on it but not staging, or the other way round. A bare domain covers its subdomains, but it does not cover a different domain. Add every host you serve the site from, including `localhost` while developing.

## 4. Is your own Content-Security-Policy blocking it?

If your site sends a `Content-Security-Policy`, it has to allow WireDesk in these directives:

| Directive                         | Why                                                                                           |
| --------------------------------- | --------------------------------------------------------------------------------------------- |
| `script-src https://wiredesk.ai`  | Loads `widget.js`. Without it, nothing draws.                                                 |
| `connect-src https://wiredesk.ai` | Lets `widget.js` fetch your saved style. Without it, the launcher draws in the default style. |
| `frame-src https://wiredesk.ai`   | Shows the conversation panel. Without it, the launcher draws but the panel is empty.          |
| `img-src` for your icon           | Only if you set an icon: allow `data:` or the https host the icon is served from.             |

A blocked script or a refused frame appears in the console as a named CSP error, not a silent failure.

## Console warnings

Each message `widget.js` logs, and what it means:

| Warning                                                                                                                                     | Meaning and fix                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[wiredesk] no widget key. Add data-widget="wk_..." to the script tag, or set window.wiredeskSettings = { key: "wk_..." } before it loads.` | The script found no key, so it drew nothing. Add `data-widget` to the tag, or set `wiredeskSettings.key` **before** the script tag.                                                                                                                                                                                                                                                                                                                                    |
| `[wiredesk] could not load the widget config (…); using defaults.`                                                                          | The saved style could not be fetched, so the launcher uses the default style (or the style cached from an earlier visit). Common causes: the domain is not on the allowed list, the key is wrong, **Website chat** is switched off for the agent, or your CSP blocks `connect-src`. Refusals come without CORS headers, so the browser often reports them as a failed fetch. Open the **Network** tab and look at the `/config` request for the real status and error. |
| `[wiredesk] this widget requires a verified visitor. Set window.wiredeskSettings.user = { id: ..., hash: ... } before the script loads.`    | **Require verification** is on, and the page gave no identity. The launcher draws, but the chat refuses anonymous visitors. Pass a signed identity, or turn the requirement off. See [verified visitors](/docs/widget/verified-visitors).                                                                                                                                                                                                                                   |
| `[wiredesk] already running for widget wk_A; ignoring wk_B.`                                                                                | Two tags with **different** keys are on the page, and the second stood down. Remove the one you do not want. Two copies of the same key are ignored silently.                                                                                                                                                                                                                                                                                                          |
| `[wiredesk] unknown command: …`                                                                                                             | A `wiredesk("…")` call used a name that does not exist. Check the spelling against the [JavaScript API](/docs/widget/javascript-api).                                                                                                                                                                                                                                                                                                                                       |
| `[wiredesk] a … listener threw: …`                                                                                                          | One of your own [event](/docs/developers/events) listeners threw an error. The widget carries on. The bug is in your listener.                                                                                                                                                                                                                                                                                                                                              |
| `[wiredesk] identity could not be serialised; continuing anonymously.`                                                                      | The `user` object could not be turned into JSON, for example because it has a circular reference. Pass plain strings for `id`, `hash`, `name` and `email`.                                                                                                                                                                                                                                                                                                             |

The config endpoint's possible errors:

| Status | Body `error`                                | Cause                                                |
| ------ | ------------------------------------------- | ---------------------------------------------------- |
| `404`  | `unknown widget`                            | The key is wrong or no longer exists.                |
| `403`  | `chat is turned off for this agent`         | **Website chat** is switched off under **Channels**. |
| `403`  | `this widget is not allowed on this domain` | The page's domain is not on the allowed list.        |

## Still nothing

* **A duplicate tag is not the cause.** A second copy of the script stands down rather than drawing a second bubble.
* **Try a private window with extensions off.** An ad or tracker blocker in your own browser can hide the launcher while every customer sees it.
* **Check the page width.** If **Hide on phones** is on, or the page sets `data-hide-on-mobile="true"`, the launcher is hidden at 480 px wide or narrower.
* **Check your own code.** A `wiredesk("hide")` call hides the launcher until `wiredesk("show")`. Also check that no overlay of yours sits above the launcher's stacking order.
* **Allow a few minutes after a WireDesk update.** `widget.js` is cached for up to five minutes.

If the tag is on the live page, the container is published, the domain is listed and the console is clean, [contact us](https://wiredesk.ai/contact) with the page URL.

## Related

* [Install the widget](/docs/widget/install)
* [Allowed domains](/docs/widget/allowed-domains)
* [Widget settings](/docs/developers/widget-settings)
* [Security model](/docs/developers/security-model)
