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

# Widget Installation

> Add the ReplyBubble chat widget to any website or platform

Add the ReplyBubble chat widget to your website. Works with any platform that supports custom HTML.

> **Time estimate:** \~3 minutes

***

## The embed snippet

Copy this from your dashboard — the **Install code** section on the dashboard home, or **Test Widget > Embed code**:

```html theme={null}
<script
  src="https://app.replybubble.com/widget/replybubble.js"
  data-widget-id="YOUR_WIDGET_ID"
  async
></script>
```

Replace `YOUR_WIDGET_ID` with your actual widget ID from the dashboard.

Paste it just before the closing `</body>` tag on every page where you want the chatbot to appear.

***

## Plain HTML

1. Open your website's HTML file
2. Find the closing `</body>` tag
3. Paste the snippet directly above it
4. Save and reload the page

```html theme={null}
<!DOCTYPE html>
<html>
  <head>
    <title>My Site</title>
  </head>
  <body>
    <!-- Your page content -->

    <!-- ReplyBubble widget -->
    <script
      src="https://app.replybubble.com/widget/replybubble.js"
      data-widget-id="YOUR_WIDGET_ID"
      async
    ></script>
  </body>
</html>
```

***

## WordPress

The easiest way to install the widget on WordPress is with our [official plugin](/integrations/wordpress). It handles everything automatically — no code editing required.

If you prefer a manual approach, use one of the methods below:

### Option A: Code Snippets Plugin

1. Install the **Insert Headers and Footers** plugin (by WPCode) from Plugins > Add New
2. Go to **Code Snippets > Header & Footer**
3. Paste the snippet into the **Footer** section
4. Click **Save Changes**

### Option B: Theme Editor

1. Go to **Appearance > Theme File Editor**
2. Open `footer.php` (in the right sidebar)
3. Paste the snippet just before `</body>`
4. Click **Update File**

> **Note:** Theme editor changes may be lost when your theme updates. The plugin method is more durable.

***

## Shopify

The easiest way to install the widget on Shopify is with our [dedicated setup guide](/integrations/shopify). It walks you through the theme editor method step by step.

If you prefer a quick manual approach:

1. Go to **Online Store > Themes**
2. Click **Actions > Edit Code** on your active theme
3. Open `theme.liquid` in the Layout folder
4. Find the closing `</body>` tag
5. Paste the snippet directly above it
6. Click **Save**

The widget will appear on all pages of your store.

***

## Squarespace

1. Go to **Settings > Advanced > Code Injection**
2. Paste the snippet into the **Footer** field
3. Click **Save**

The widget will appear on every page of your site.

***

## Wix

1. Go to your site's **Dashboard > Settings**
2. Click **Custom Code** (under Advanced)
3. Click **Add Code**
4. Paste the snippet
5. Set placement to **Body - end**
6. Choose to apply to **All pages**
7. Click **Apply**

***

## Webflow

1. Go to **Project Settings > Custom Code**
2. Paste the snippet into the **Footer Code** section
3. Click **Save Changes**
4. **Publish** your site for changes to take effect

### Per-page installation

If you only want the widget on specific pages:

1. Open the page in the Webflow Designer
2. Go to **Page Settings > Custom Code**
3. Paste the snippet into the **Before body closing tag** section
4. Save and publish

***

## Google Tag Manager

1. In GTM, go to **Tags > New**
2. Choose **Custom HTML** as the tag type
3. Paste the snippet
4. Set the trigger to **All Pages** (or specific pages)
5. Click **Save** and **Publish**

> **Note:** Loading the widget through GTM adds a small delay since it loads asynchronously through GTM's container. In most cases this is not noticeable.

***

## Verifying installation

After adding the snippet:

1. Open your website in a new browser tab (or hard-refresh with Ctrl+Shift+R)
2. Look for the chat bubble in the bottom-right corner of the page
3. Click it and send a test message
4. Verify the bot responds using your knowledge base content

### If the widget doesn't appear

* **Check your widget ID** — make sure it matches the one in your dashboard
* **Check for JavaScript errors** — open your browser's developer console (F12) and look for errors
* **Check your CSP headers** — if your site uses Content Security Policy, you need to allow `*.replybubble.com`. See [Troubleshooting](/troubleshooting) for details
* **Wait a moment** — the widget script loads asynchronously and mounts once the page's HTML has finished parsing

***

## Advanced options

### Custom API URL

If you're using a self-hosted or custom API endpoint, add the `data-api-url` attribute:

```html theme={null}
<script
  src="https://app.replybubble.com/widget/replybubble.js"
  data-widget-id="YOUR_WIDGET_ID"
  data-api-url="https://your-custom-api.com"
  async
></script>
```

### Disabling the widget on specific pages

The simplest approach is to only include the widget script on pages where you want it. If your templates always include it, you can remove the widget after load instead:

```html theme={null}
<script>
  window.ReplyBubble?.destroy();
</script>
```

You can bring it back later in the same page session with `window.ReplyBubble.init({ widgetId: "YOUR_WIDGET_ID" })`. This is useful for admin pages, checkout flows, or anywhere you don't want the chatbot to appear.

### Identifying logged-in users

If your visitors are authenticated, you can link their chat conversations to their identity. See [User Verification](/user-verification) for the full setup guide.

```javascript theme={null}
window.ReplyBubble.identify({
  id: "user-123",
  email: "jane@example.com",
  name: "Jane Doe",
  signature: "hmac-from-your-server",
});
```

***

## Widget JavaScript API

Beyond the declarative `data-*` attributes, `window.ReplyBubble` exposes a small programmatic API for controlling the widget from your own code.

| Method                 | Description                                                                                                                                                    |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `init(config)`         | Mounts the widget. Idempotent — only the first call takes effect until `destroy()` is called.                                                                  |
| `destroy()`            | Tears down the widget and its DOM, allowing a later `init()` call to remount it.                                                                               |
| `identify(user)`       | Links the current conversation to an authenticated user. Must be called after `init()`. See [Identifying logged-in users](#identifying-logged-in-users) above. |
| `reset()`              | Clears the current identity and starts a fresh, anonymous conversation.                                                                                        |
| `open()`               | Programmatically opens the widget.                                                                                                                             |
| `close()`              | Programmatically minimizes the widget.                                                                                                                         |
| `toggle()`             | Opens the widget if closed, closes it if open.                                                                                                                 |
| `on(event, callback)`  | Subscribes to a widget event. Returns an unsubscribe function.                                                                                                 |
| `off(event, callback)` | Unsubscribes a previously registered event handler.                                                                                                            |

### Events

`on()` supports three events, matching the callback style used by Intercom and Crisp:

* `'open'` — fires when the widget expands
* `'close'` — fires when the widget minimizes
* `'unread'` — fires when the unread count changes; the handler receives the new count as its only argument

```javascript theme={null}
const unsubscribe = window.ReplyBubble.on("unread", (count) => {
  document.title = count > 0 ? `(${count}) My Site` : "My Site";
});

// Later, to stop listening:
unsubscribe();
// or: window.ReplyBubble.off("unread", handler);
```

### Loading asynchronously (queue pattern)

If you load the widget script with `async`, `window.ReplyBubble` may not exist yet when your own code runs. Queue the config before the script loads and it's picked up as soon as the script finishes loading:

```html theme={null}
<script>
  window.ReplyBubble = { _q: [{ widgetId: "YOUR_WIDGET_ID" }] };
</script>
<script src="https://app.replybubble.com/widget/replybubble.js" async></script>
```

Only the first queued config is used if more than one is pushed to `_q`.

For the full visitor-facing feature set (file attachments, CSAT, conversation history, reactions, and more), see [Widget Features](/widget-features).

***

## Languages

The widget UI ships in 15 languages: Arabic, German, English, Spanish, French, Hindi, Italian, Japanese, Korean, Dutch, Polish, Brazilian Portuguese, Russian, Turkish, and Simplified Chinese. Arabic renders right-to-left automatically. Locale is configured through workspace or personality settings on the dashboard — not a `data-*` embed attribute.

<Info>
  Non-English widget UI translations are a **Pro** plan feature — Free-plan workspaces always show the English widget regardless of visitor locale.
</Info>

See [Widget Features](/widget-features#languages) for more detail.
