# Website chat

> Add the Airhug chat widget to your website with one script tag, in Framer, React or any site builder. Approved-origin rules, appearance, browser calling, and how to test.

Source: https://docs.airhug.ai/channels/website-chat
Last updated: 2026-09-29

The website chat widget is a launcher on your site that opens a chat with the same AI that answers your phone. It uses the same knowledge, greeting, rules and transfer settings. It can also start a real voice call in the browser.

## Set it up

Go to **Settings → Channels → Website chat** and choose **Set up website chat**.

1. **Website and agent.** Enter your **Website address**, with `https://`, for example `https://clinic.com`. The widget loads only on this exact HTTPS origin and its `www` twin. Choose the phone line whose agent the chat should use. The chat inherits that line's name, knowledge, guardrails and transfer rules. There is no separate web persona.
2. **Appearance.** Pick the **Agent orb color**, **Button color** and **Button icon**.
3. **Visitor access.** Turn on **Enable website chat**. Nothing opens for visitors until you enable and save it. Turn on **Let visitors call from chat** only if you want a call button.
4. **Install.** Copy the snippet and paste it once, just before `</body>`, on every page.
5. **Test and verify.** Two checks and one real conversation. See below.

## The snippet

```html
<script async src="https://api.airhug.ai/widget/v1.js" data-airhug-widget="pub_xxxxxxxx"></script>
```

That is the whole install. It works in Squarespace, Wix, WordPress, Shopify and anything else with a "custom code" or "footer scripts" box. On WordPress, use your theme footer or a header-and-footer scripts plugin. Publish the site: the snippet does nothing until the page is live.

The `pub_…` key is not a secret. It is in your page HTML either way, and it works only on the approved origin. **Never put an API token on a website.**

## Framer

Use the site-wide script, not the component. Framer routes between pages on the client, so a code component dropped on one page unmounts, and takes the launcher with it, when a visitor navigates.

Framer: **Project Settings → Custom Code → Add Script**.

| Field | Value |
| --- | --- |
| Placement | End of body |
| Page | All pages |
| Run | Once |
| Code | The snippet above |

The **Add Script** box takes `<script>…</script>` HTML only. Do not paste the component's source there.

Use the **code component** instead only when a designer wants controls in Framer's property panel, or the widget on some pages only. In the app, choose **Copy Framer component**, then in Framer: **New Code File → New Component** (not an Override), paste, drop it on the page, and fill in **Widget key**. To share the component, copy its URL from **Assets → Code**, and strip the `@…` version suffix so the link always serves the latest.

## React, Next.js, Vite

```tsx
import { AirhugWidget } from "@airhug/widget-react";

export default function Layout({ children }) {
  return (
    <>
      {children}
      <AirhugWidget publicKey="pub_xxxxxxxx" />
    </>
  );
}
```

In the Next.js App Router, use it inside a client component because it touches the DOM.

## Appearance overrides

Set appearance in the app. Changing it there updates every site the widget is installed on. To override for one site, pass props or data attributes. **A blank value means "use the app setting".**

```tsx
<AirhugWidget publicKey="pub_xxxxxxxx" orbColor="#7c3aed" launcherColor="#18181b" launcherIcon="headset" />
```

```html
<script async src="https://api.airhug.ai/widget/v1.js" data-airhug-widget="pub_xxxxxxxx"
  data-airhug-orb-color="#7c3aed" data-airhug-launcher-color="#18181b"
  data-airhug-launcher-icon="headset" data-airhug-voice="off"></script>
```

- Colors are six-digit hex.
- Icons: `chat`, `message`, `phone`, `headset`, `help`, `sparkle`. Anything else is ignored.
- `voice` off (or `data-airhug-voice="off"`) hides the call button on that site. It is off-only by design: a site cannot switch calling on.
- If you upload an avatar, it replaces the orb everywhere.

## Calling from the browser

The call button appears only when both are true: you turned on **Let visitors call from chat**, and the phone line's account can create browser calling tokens. Numbers provisioned by Airhug already can. A number on your own Twilio account needs an API key and a TwiML app. See [phone numbers](https://docs.airhug.ai/channels/phone-numbers.md).

## Test it

1. Load your site. The launcher appears bottom-right within a second or two.
2. Click it. The panel opens from the button.
3. Send a test chat. The first one asks for a name, email and consent.
4. Open **Inbox → Website** and confirm the conversation arrived.

The **Test and verify** panel shows "Airhug has not detected the widget loading on your approved website yet" until the widget loads once from your approved origin. That proves the origin loaded it. It does not prove a visitor conversation or reply was delivered, so still send a real test message.

### Testing on a preview or staging domain

A Framer preview at `https://your-site.framer.app` is a different origin, so the widget stays hidden. To try it before launch, set **Website address** to the preview domain, test, then set it back to the real one before going live. The browser console says why the widget did not start:

```text
[airhug] chat could not start (origin_not_allowed). This page is https://your-site.framer.app,
which is not the website address set in Settings → Website chat.
```

## Nothing appears?

Check in this order.

1. The snippet is on the page and the key matches the one in Settings.
2. **Enable website chat** is on and saved.
3. **Website address** matches the browser address bar exactly, including `https://`. `http://` does not match. A different subdomain does not match.
4. The browser console. A `frame-ancestors` violation means the address in Settings is wrong for this site.

## Staff replies

When a teammate takes over a conversation, visitors see that teammate's display name. Staff are asked for a display name the first time they take over. Escalations notify every active member of the workspace. Lock-screen notifications say only that someone on your website is waiting for a person. They never include the visitor's name or message.

## Tokens

Each AI reply in chat costs 2 tokens. A call from the chat costs 10 tokens per minute, like a phone call. See [AI tokens](https://docs.airhug.ai/billing/ai-tokens.md).
