
# Chat Widget

## Website Chat Widget Integration Guide

Add a user-friendly chat widget to your website that enables visitors to communicate directly through your site's interface. The integration process is straightforward and will provide your website with built-in messaging capabilities.

::: walkthrough chat-widget
:::

### Creating and Configuring the Chat Widget

**How to get there:**

1. Click **Settings** near the bottom of the left sidebar. (On a phone, first tap the menu icon **☰** in the top corner to open the sidebar.)
2. In the Settings left rail, under **Channels**, click **Channels**.
3. Find the **Website chat widget** card.
4. If you don't have a widget yet, click **Connect** to create one with a display name and welcome message.
5. Once created, click **Manage** any time to open the full configuration panel.

::: master-only
<figure><img src="../.gitbook/assets/v2-channels-overview.png" alt="The top of the Channels page — the Website chat widget card is further down the same list"><figcaption><p>The chat widget gets its own card on the Channels page — Connect to create it, Manage to configure everything else. It sits further down the list than shown here, past Instagram (Personal), LINE, Email, and the other channels.</p></figcaption></figure>
:::

Changes you save apply to your live widget automatically — there's no need to re-paste the install code after making a change.

A **Live preview** sits right next to the settings: a sample web page with your actual widget running on it, showing your colors, position, logo, launcher icon and proactive popup exactly as visitors will see them. It follows your edits as you make them, so you don't have to save to see what a color or theme change looks like. You can even click the chat button inside the preview to open the widget and try it out.

### What You Can Customize

The Manage panel is organized into four sections.

#### Appearance

- **Style theme:** Restyle the whole widget in one click. Six themes each set the look, colors, corners and font together: **Classic** (the original solid look — a colored header bar on a flat panel), **Glass** (a frosted, translucent panel that softly blurs the page behind it, with the header and message box floating as rounded cards inside it), **Midnight** (Glass in dark colors), **Bloom** (soft pink, extra-rounded), **Ember** (warm orange Glass) and **Mono** (black-and-white, sharp corners). A theme is a starting point — after picking one you can still change any color or knob individually. New widgets start on Glass; switching is instant everywhere the widget is embedded, with no code changes on your site.
- **Corners and Font:** Two independent style knobs. **Corners** sets how rounded the panel, bubbles and buttons are (Round, Soft or Sharp), and **Font** picks the typeface visitors see (Default, Serif, Rounded or Mono) — fonts come from what's already on the visitor's device, so nothing extra loads on your site.
- **Display name:** Shown in the widget header.
- **Logo:** Upload an image that appears at the top of the chat. Use your company logo or a friendly headshot.
- **Launcher icon:** The icon on the floating chat button itself. Pick one of the built-in icons (chat bubble, paper plane, question mark, and more), reuse your uploaded logo, or upload a separate image of your own — handy if you want a photo of a real team member greeting visitors.
- **Colors:** Five colors, each one naming the part of the widget it paints. **Brand color** is the floating button, the header, and the visitor's own messages, with **Brand text** for the text sitting on top of it. **Bot bubble** is the background of your bot's replies and of the typing indicator, with **Bot bubble text** for the words inside them and the animated typing dots. **Chat window** is the panel behind all the messages. Pick a Bot bubble color that is clearly different from your Brand color — if the two match, both sides of the conversation come out the same color and visitors can't tell your bot's replies apart from their own. A light grey bot bubble with dark text next to your brand color is the safe combination.
- **Position:** Place the floating chat button in the **bottom-right** or **bottom-left** corner, with horizontal and vertical offset (in pixels) if it overlaps something else on your page.
- **Starter questions:** Quick-reply suggestions (clickable chips) shown in the chat so visitors can get going with one tap instead of typing — for example "What are your prices?" or "Do you offer support?" — up to 10.

::: master-only
<figure><img src="../.gitbook/assets/v2-channel-widget-config.png" alt="The Chat widget configuration panel, showing the six style theme cards (Classic, Glass, Midnight, Bloom, Ember, Mono), the Corners and Font pickers, Display name, Logo, Launcher icon, and the Colors pickers on the left, with the Live preview on the right showing the widget open in the Glass theme"><figcaption><p>The Manage panel's Appearance section. The theme cards at the top restyle the whole widget in one click — here Glass is selected, and the preview on the right shows the frosted panel with its floating header and message box. The Launcher icon row shows the built-in icons in your widget's own colors, and each color picker says which part of the widget it paints. The preview follows your edits live; saving publishes them to your site.</p></figcaption></figure>
:::

#### Behavior

- **Opening message:** The first message visitors see when they open the chat (for example, "How can I help you?").
- **Sound:** Play a sound when a new message arrives in the chat.
- **Ask notification permission:** Optionally prompt visitors to allow browser notifications, so they're alerted to replies even when they've switched tabs.
- **Proactive popup bubble:** An optional little bubble that pops up next to the chat button to invite people in. Turn it on to set its message, the accept/decline button text, and how many seconds to wait before it appears. The bubble hides itself again after 20 seconds if nobody clicks it (that number is fixed), and once a visitor clicks **Not now** it stays away for the rest of their visit. The chat window itself never opens on its own: it opens when the visitor clicks the chat button or the bubble, and stays open until they close it.
- **AI response speed:** A slider between **Slower** (more human — the AI takes a beat before replying) and **Max speed** (more robotic — replies come back as fast as possible). Balanced sits in the middle.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-behavior.png" alt="The Behavior section of the Manage panel, showing Opening message, Sound, Ask notification permission, Proactive popup bubble, and AI response speed fields"><figcaption><p>The Behavior section. Sound and Ask notification permission are simple toggles; Proactive popup bubble expands to its own message/button/delay fields once turned on.</p></figcaption></figure>
:::

#### Languages

The widget is multilingual on its own — there's nothing to switch on.

- **It picks the visitor's language automatically.** First it looks at the language your page declares in its HTML (`<html lang="it">`), then it falls back to the visitor's browser language. If neither is a language we support, the widget's own labels show in English and your opening message, popup bubble and starter questions appear exactly as you wrote them.
- **Or pick one yourself.** The **Widget language** field in the Behavior section is set to Auto by default, which is the detection above. Choose a language there and the widget's own labels (the visitor form's First name, Email and Phone fields and their example text, the privacy notice, the buttons) stay in that language whatever the page or browser says. Use this when your site builder does not declare the right language, or when you want one fixed language for every visitor.
- **Supported languages:** English, Dutch, German, French, Spanish, Italian, Portuguese, Romanian, Polish, Arabic, Finnish, Filipino, Slovenian, Thai, Bangla and Japanese. This is the list for the widget's own buttons and labels.
- **Your messages are translated for you.** Every time you save, your opening message, proactive popup bubble and starter questions are translated into all sixteen languages above. You only ever write them once, in whichever language you prefer: the language you wrote in is recognised from the text itself, that version is kept word for word, and every other language is a translation of it. It does not matter which language your account is set to.
- **Write each message in one language only.** If you put two languages in the same field — an English line and an Italian line, say — the whole thing is treated as a single message and translated as it stands, so an Italian visitor ends up seeing the same sentence twice. Write it once, in whichever language you prefer.
- **The AI replies in the visitor's language.** Whatever language someone types in, your agent answers in that same language, regardless of which language the widget's labels are showing. If you'd rather it always answer in one fixed language, say so in your agent's instructions.

**Tip:** if your website doesn't set a `lang` attribute on its `<html>` tag, add one. It's the strongest signal we have for picking the right language, especially for visitors browsing from abroad.

#### Lead Capture & Privacy

- **Collect visitor info:** Off by default. When on, visitors are asked for their name and email (and optionally phone) before the conversation begins, so you capture the lead even if they leave mid-chat.
- **Form title** and **Form subtitle:** Customize the heading and short explanation shown above the form.
- **Collect phone number:** Turn on to also ask for a phone number; off collects only name and email.

> **A visitor left a phone number and is gone from your site — can I continue on WhatsApp?** Yes. Open their chat and choose **Continue on WhatsApp** from the three-dot menu (WhatsApp Web or WhatsApp Business needs to be connected). <span data-t="appName">DM Champ</span> creates a linked WhatsApp conversation for the same person, copies their name, email and details across, and the AI carries over what they said on your site, so nobody has to repeat themselves. The website chat stays where it is and both chats point at each other under **Linked conversations** in the contact panel. See [Chat Interface](../chats/chat-interface.md).

> **Can the AI agent offer the switch to WhatsApp itself?** Yes, and it needs no extra feature — one line in the agent's instructions does it. Create a [Short Link](../settings/short-links.md) for your WhatsApp number with a prefill message such as "Hi, I was chatting on your website and want to continue here", then tell the agent when to send it, for example: "If the visitor needs to leave, wants to continue later, or asks for WhatsApp, offer to carry on there and send this link: (your short link)". Links in the widget are tappable, so the visitor lands in WhatsApp with your number selected and the message pre-typed, and their first message opens a WhatsApp conversation in your inbox. If the visitor left the phone number they write from (with country code) in the widget form, <span data-t="appName">DM Champ</span> links the two conversations automatically and the AI on WhatsApp already knows the website chat, exactly as with **Continue on WhatsApp**. If no phone number was collected, the two chats are not linked, so keep the prefill message specific enough that the WhatsApp agent knows where the person came from.
- **Require privacy policy acknowledgement:** Optionally require visitors to accept your privacy policy before chatting, and set the URL it points to.

> **What does the widget store in a visitor's browser, and do I need to put it behind a cookie banner?** Nothing is stored just by loading a page. The widget writes no cookies and no browser storage until the visitor chooses to chat: sends a first message, fills in the visitor info form, or accepts your privacy policy. From that moment it keeps a random conversation ID and a copy of the conversation in that browser, as first-party storage on your own domain, so the chat is still there when they come back. It loads no analytics or tracking scripts and sets no third-party cookies. Because nothing is written until the visitor asks to chat, it falls under the storage that is strictly necessary for a service the visitor requested, so you can load it without gating it behind a consent banner. If your site uses a consent tool anyway, it is fine to keep the widget behind it; the chat simply appears once the visitor accepts.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-lead-capture-privacy.png" alt="The Lead Capture & Privacy section of the Manage panel, showing Collect visitor info, Form title, Form subtitle, Collect phone number, and Require privacy policy acknowledgement"><figcaption><p>The Lead Capture & Privacy section. With Collect visitor info on, visitors see this as a small form before the conversation starts — shown from the visitor's side further down this page.</p></figcaption></figure>
:::

#### Channels & Embed

- **Attachment button:** Lets visitors send images and files in the chat.
- **Emoji picker:** Adds an emoji picker next to the message box.
- **Channel links:** Optionally include WhatsApp, Instagram, or Messenger links so visitors can continue the conversation on the platform they prefer. This only appears once you've connected a WhatsApp number, Instagram, or Messenger.
- **Action buttons:** A row of shortcuts across the top of the chat that take the visitor somewhere instead of into a conversation — see [Action buttons](#action-buttons) below.
- **Domain whitelist:** Restrict which websites are allowed to embed your widget. Add the domains where you've installed it (e.g. `example.com` or `*.example.com`); leave empty to allow any domain.
- **Blocked countries:** Keep the widget away from visitors in countries you don't serve. Visitors whose network location is in a country you pick never see the widget, and any chat they try to start is refused. Leave empty to allow everyone. See [Keeping bots and credit drain out](#keeping-bots-and-credit-drain-out) below.
- **Route these chats to:** Pick the campaign or agent that should handle chats coming from the code you're about to copy. Leave it on **Account default** to use your normal chat widget routing. See [Send different pages to different campaigns](#send-different-pages-to-different-campaigns) below.
- **Embed snippet:** Choose **Floating bubble** or **Inline** and copy the install code (see below).
- **Client demo link:** Paste any website address to get a shareable link that opens that site with your widget running on top of it — nothing to install on their end. See [Show the widget on someone else's website](#show-the-widget-on-someone-elses-website) below.

At the bottom of the panel, a **Delete chat widget** action removes the widget from your website immediately — this can't be undone, and visitors will no longer see the chat bubble.

#### Action buttons

Some visitors don't want to chat. They want your phone number, your address, or your email, and they want it in one tap. Action buttons are a row of shortcuts across the top of the chat panel for exactly that.

Add up to six. Each one has a **label** (the words on the button) and a **destination**, and the destination depends on which action you pick:

| Action | What the visitor gets | What you fill in |
| --- | --- | --- |
| **Call** | Their phone dialler opens with your number ready | Your phone number, e.g. `+1 555 123 4567` |
| **Text** | Their messaging app opens a new text to you | Your phone number |
| **WhatsApp** | WhatsApp opens a chat with you | Your WhatsApp number, or a `wa.me` link you already have |
| **Email** | Their mail app opens a new email to you | Your email address |
| **Directions** | Google Maps opens with your location | Your address, or a maps link you already have |
| **Link** | The page opens in a new tab | Any full web address starting with `https://` |

**These buttons don't use credits.** Tapping one doesn't send a message and doesn't start a conversation — it just takes the visitor where they asked to go. Only an actual conversation with your AI agent uses credits, exactly as before.

A few things worth knowing:

- **The buttons stay visible while the visitor chats.** Someone can ask two questions and still tap **Directions** afterwards without reloading the page.
- **Your labels are shown exactly as you wrote them.** Unlike your opening message and starter questions, button labels are not auto-translated, so if you serve visitors in several languages, keep the labels short and obvious (or write them in your main language).
- **Fill a button in properly or it won't save.** If a phone number, email address or link isn't valid, the panel says so and blocks **Save changes** rather than publishing a button that would do nothing on your site.
- **They're not FAQ answers.** Action buttons only send people elsewhere; they don't reply with canned text. Questions are your AI agent's job, and it answers them from your knowledge base. If you want to suggest what to ask, use **starter questions** under Appearance instead.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-action-buttons.png" alt="The Action buttons section of the Manage panel, with three buttons added: Call labelled Call us, Directions labelled Find us, and WhatsApp"><figcaption><p>Three action buttons being set up. Each row is an action, the text on the button, and where it should go. Add button adds another, up to six.</p></figcaption></figure>
:::

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-action-strip.png" alt="The chat widget open on a website with a row of three action buttons across the top: Call us, Find us and WhatsApp"><figcaption><p>What the visitor sees. The buttons sit above the conversation and stay there while they chat, so they can tap one at any point.</p></figcaption></figure>
:::

#### What you can't customize

The Manage panel is the whole set of options. In particular:

- **No custom CSS or stylesheet.** Styling is what the theme, corner, font and colour pickers offer — you can't inject your own CSS into the widget, and rules on your page won't reach inside it.
- **No custom placeholder text** in the message box.
- **No video embedding** inside the chat.
- **No auto-hide timer.** The invitation bubble disappears on its own after 20 seconds and that number can't be changed; the open chat window never closes itself. If the bubble sits over your page content, move the widget with the **Position** offsets or turn the bubble off and keep just the launcher button.

If one of those is a blocker for you, the [inline embed](#embed-inline-on-a-page-advanced) gives you the most control: the widget sits in a container on your own page, which you size and position yourself.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-channels-embed.png" alt="The Channels & Embed section of the Manage panel, showing Domain whitelist, Route these chats to, the Embed snippet code box, the Client demo link field with a website address typed in and its generated link below, and the Delete chat widget danger zone"><figcaption><p>The Channels & Embed section, with the ready-to-copy install snippet, the Client demo link below it, and the Delete chat widget action at the bottom. Here a client's website has been typed into the demo field and the shareable link has appeared underneath it. Both the snippet and the demo link shown here are specific to this account — copy your own from your Manage panel, not these.</p></figcaption></figure>
:::

### Keeping Bots and Credit Drain Out

Every AI reply costs credits, so a script (or one bored person) opening chat after chat on your website is the one thing a public widget has to defend against. The widget handles most of it on its own, and two settings on the Manage panel let you tighten it for your site.

- **Domain whitelist.** Only the websites you list can show the widget. Anyone who copies your embed code onto another site gets nothing.
- **Blocked countries.** Visitors whose network location is in a country you block never see the widget, and a chat they try to start anyway is refused. The location comes from the visitor's connection: someone on a VPN shows up as the VPN's country, and a visitor whose location can't be determined is let through rather than shut out. Your own preview inside the app keeps working even if you block the country you are sitting in.
- **New conversations per connection.** One connection (in practice one household or office address) can open 20 new conversations per day on a widget. Returning visitors continuing their existing chat don't count, only brand-new conversations do, so a script that keeps starting fresh chats to farm AI replies runs dry after 20 while real visitors never notice. If many people share one connection on your site (a campus, a call centre), raise the number over the [REST API](../api/reference.md) with `max_new_chats_per_ip_daily`; `0` switches the check off.
- **Built-in limits.** On top of that, each browser session is capped in how many messages it can send per minute and per day, and the agent answering the chat stops replying to a visitor once it reaches the **Max AI messages per chat** set under its **Response limits**.

None of this identifies devices or people: the widget stores nothing in a visitor's browser until they choose to chat (see above), and there is no fingerprinting.

### Installation Instructions

To add the chat widget to your website, add one line of code to your site's HTML.

1. Open your website's HTML file in a text editor.
2. Find the closing `</body>` tag — this is usually at the very end of the file.
3. Paste this line of code just before the `</body>` tag, so the rest of your page loads first:

{% code overflow="wrap" %}
```html
<script src="https://api.dmchamp.com/v1/chat-widget/CONFIG_ID"></script>
```
{% endcode %}

4. Replace `CONFIG_ID` with your unique configuration identifier, shown in the **Channels & Embed** section of the Manage panel. This identifier is specific to your account and connects the widget to your messaging system.

The snippet won't slow your site down: it's a tiny loader, and the widget itself downloads in the background without blocking the page. If you'd still like the widget to hold back until your page has completely finished loading, you can wrap the same URL like this instead:

{% code overflow="wrap" %}
```html
<script>
window.addEventListener('load', function () {
  var s = document.createElement('script');
  s.src = 'https://api.dmchamp.com/v1/chat-widget/CONFIG_ID';
  s.async = true;
  document.body.appendChild(s);
});
</script>
```
{% endcode %}

And if what you want to delay is the little invitation bubble rather than the widget loading, that's the **Proactive popup bubble** delay in the Behavior section above — no code needed.

Here's a complete example of how your HTML file should look with the chat widget implemented:

{% code overflow="wrap" %}
```html
<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
</head>
<body>
    <!-- Your existing website content would be here -->

    <!-- Chat Widget Integration -->
    <script src="https://api.dmchamp.com/v1/chat-widget/CONFIG_ID"></script>
</body>
</html>
```
{% endcode %}

### Embed Inline on a Page (Advanced)

If you'd rather have the chat appear as part of your page — for example inside a dedicated "Contact us" section, a help tab, or a sidebar — instead of as a floating bubble in the corner, switch **Embed snippet** to **Inline** in the Manage panel and copy the inline snippet.

It looks like this:

{% code overflow="wrap" %}
```html
<div data-chat-widget="CONFIG_ID" style="width:100%;height:600px;"></div>
<script src="https://api.dmchamp.com/v1/chat-widget/embed.js" async></script>
```
{% endcode %}

The `<div>` is the mount point — the chat panel renders inside it and fills its dimensions. Style the div however you like (give it a fixed height, drop it inside a flex container, place it in a grid cell, etc.) and the chat panel will follow.

You only need **one** `<script>` tag on the page, even if you're embedding multiple chat widgets. The script scans the page for every `<div data-chat-widget="…">` and mounts a chat panel in each.

When to pick inline vs floating:

- **Floating bubble** is right for a sitewide always-available "Need help?" button.
- **Inline embed** is right when chat should live in a specific place — a support page, a knowledge-base sidebar, an in-app help tab — and feel like a native part of that page.

The inline embed reuses the same configuration as the floating bubble (logo, opening message, lead capture, starter questions, and so on), so you don't have to set anything up twice.

### Show the Widget on Someone Else's Website

You can show your chat widget running on a website you don't control — no code, no access to their site needed. It's the fastest way to show a prospect what the assistant would look like on their own pages.

1. Open the Manage panel and scroll to **Channels & Embed**.
2. In **Client demo link**, type the website address (for example `www.theircompany.com`).
3. Click **Copy** to copy the link, or **Open** to see it yourself first.
4. Send the link to whoever you want to show it to.

Opening the link loads that website with your chat widget floating on top, exactly as it would look if it were installed. Anyone with the link can open it — there's nothing to log into.

A few things worth knowing:

- **Chats from the demo are real.** Messages a visitor sends in a demo arrive in your inbox and are answered by your agent, and they use credits like any other conversation.
- **The page is unbranded.** It shows their website and your widget, and nothing else.
- **Some websites can't be framed.** A number of sites (banks, large retailers, anything behind strict security settings) block other pages from displaying them. When that happens the link still works: it shows a neutral mock browser window instead of the real site, with your widget live on top so the demo still does its job.
- **It doesn't change their website.** Nothing is installed and nothing is modified — the demo only exists inside that link.

{% hint style="info" %}
The demo link always uses your account default routing, no matter what **Route these chats to** is set to. If you want demo chats handled by a specific agent, set that agent as your chat widget default first.
{% endhint %}

### Send Different Pages to Different Campaigns

By default, every chat that comes in through your widget is handled by the same campaign or agent. You can override that per page, so visitors on your pricing page talk to your sales campaign while visitors on your help page talk to your support agent — all from the one chat widget.

There are two ways to get the code:

- **From the campaign or agent.** On the **Campaigns** page, open the **⋮** menu on a campaign and choose **Add to website**. On the **Agents** page, click the **&lt;/&gt;** button on the row, or open the agent and go to its **Entry points** tab. Either way you get a ready-to-paste snippet already pointed at that campaign or agent.

  An agent's **Entry points** tab also has a **Website chat widget** panel showing how many website chats that agent is already handling. Chats from an embed reach the agent directly, so you do **not** need to create an entry point rule for them — an agent with no rules at all still answers its embed.

  **Add to website** only appears on campaigns that are live and set up to handle incoming chats. A draft campaign can't receive visitors yet, so the option is hidden until you publish it. On the Agents page it appears on active agents. A paused agent would receive the chat but never reply, so the option is hidden until you switch it back on. There is no channel to set up for an agent — an agent can pick up a chat from any channel.
- **From the widget settings.** In **Settings → Channels → Manage** on your chat widget, set **Route these chats to** and copy the snippet underneath. Changing the dropdown rewrites the snippet.

The floating snippet carries the destination in the address:

{% code overflow="wrap" %}
```html
<script src="https://api.dmchamp.com/v1/chat-widget/CONFIG_ID?campaign=CAMPAIGN_ID"></script>
```
{% endcode %}

The inline snippet carries it on the `<div>` instead, so one page can hold several chats going to different places:

{% code overflow="wrap" %}
```html
<div data-chat-widget="CONFIG_ID" data-campaign="CAMPAIGN_ID" style="width:100%;height:600px;"></div>
<script src="https://api.dmchamp.com/v1/chat-widget/embed.js" async></script>
```
{% endcode %}

For an agent, the wording changes to `?agent=AGENT_ID` or `data-agent="AGENT_ID"`.

A few things worth knowing:

- Use the copy button rather than typing the ID by hand. If the ID doesn't match a campaign or agent on your account, the chat still works but falls back to your default routing.
- Someone who is already mid-conversation stays with whoever they started with, even if they later land on a page pointing somewhere else. This keeps a conversation from switching personality halfway through.
- A page-specific destination takes priority over your account default and over keyword triggers.

### Tell the Widget Who the Visitor Is (Advanced)

If you put the chat widget inside a members area, a customer portal or an app where people are already signed in, your site already knows who they are. You can hand that over to the widget so the visitor isn't asked for details they've given you before, and so your AI can use what you already know about them.

Add a small settings block **before** the widget script:

{% code overflow="wrap" %}
```html
<script>
  window.chatWidgetSettings = {
    visitor: {
      id: "12345",
      name: "Maria",
      email: "maria@example.com",
      phone: "+391234567890"
    },
    data: {
      plan: "Professional",
      customer_since: "2024",
      last_order: "A-2291"
    }
  };
</script>
<script src="https://api.dmchamp.com/v1/chat-widget/CONFIG_ID"></script>
```
{% endcode %}

Your page should fill those values in server-side, from whoever is logged in.

Two things happen:

- **The "Before we start..." form is skipped.** With a name and an email supplied, the visitor goes straight into the conversation, and those details are saved on their contact exactly as if they had typed them.
- **Everything under `data` is handed to your AI.** Anything you put there — plan, order number, renewal date, credit balance, how many seats they have — becomes part of what the AI knows about that person, so it can answer "when does my plan renew?" without asking them to explain who they are first. Use whatever field names make sense to you; they show up on the contact under Custom Fields. Up to 20 values, sent fresh with every message, so if the plan changes mid-conversation the AI sees the new one.

For inline embeds, you can put the same information on the `<div>` instead, which is handy when one page holds several chats:

{% code overflow="wrap" %}
```html
<div data-chat-widget="CONFIG_ID"
     data-visitor-name="Maria"
     data-visitor-email="maria@example.com"
     data-visitor-data='{"plan":"Professional"}'
     style="width:100%;height:600px;"></div>
<script src="https://api.dmchamp.com/v1/chat-widget/embed.js" async></script>
```
{% endcode %}

If your site only knows who the visitor is after the page has loaded — a single-page app where signing in happens without a page reload, for example — call this whenever you have the details, and the widget updates itself:

{% code overflow="wrap" %}
```html
<script>
  window.chatWidget.setVisitor({
    visitor: { id: "12345", name: "Maria", email: "maria@example.com" },
    data: { plan: "Professional" }
  });
</script>
```
{% endcode %}

A few things worth knowing:

- If two different people sign in on the same computer, the second one starts a fresh conversation rather than seeing the first one's chat. The widget notices the change of person and resets itself.
- On its own, this is for context, not for logging someone in. Conversations are still kept separate the way they always were, so passing an `id` doesn't let anyone open somebody else's chat, and someone using a different device or browser starts a new conversation there. To carry the conversation across devices, sign the `id` as described next.
- It's optional. A widget on a normal public page needs none of this and behaves exactly as before.

#### Resume the same conversation on any device (signed visitor ID)

If your customers have accounts, you can make their chat follow them: sign in on a phone, continue on a laptop, and it is the same conversation with the same contact in your inbox, and the AI still knows everything that was said. For that, <span data-t="appName">DM Champ</span> needs proof that the visitor really is who your page says they are, otherwise anyone could type a customer number into their browser and read that customer's chat. The proof is a signature you compute on your server.

1. In the widget's **Manage** panel, under **Channels & Embed**, find **Signed-in visitors** and click **Generate secret**. Copy the identity secret. Keep it on your server only; never put it in the page itself.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-signed-visitors.png" alt="The Signed-in visitors row in the chat widget's Manage panel, showing the masked identity secret with Show, Copy and Regenerate buttons, and the settings snippet with the id and hash fields underneath"><figcaption><p>The Signed-in visitors row under Channels &amp; Embed. The secret stays hidden until you click Show; the snippet underneath shows where the id and its signature go on your page.</p></figcaption></figure>
:::
2. When your server renders a page for a signed-in customer, compute an HMAC-SHA256 of that customer's ID using the secret, as a lowercase hex string:

{% code overflow="wrap" %}
```js
// Node.js
const hash = require("crypto").createHmac("sha256", IDENTITY_SECRET).update(customerId).digest("hex");
```
{% endcode %}

{% code overflow="wrap" %}
```php
// PHP
$hash = hash_hmac('sha256', $customerId, IDENTITY_SECRET);
```
{% endcode %}

{% code overflow="wrap" %}
```python
# Python
import hmac, hashlib
hash = hmac.new(IDENTITY_SECRET.encode(), customer_id.encode(), hashlib.sha256).hexdigest()
```
{% endcode %}

3. Put the ID and the hash in the settings block, next to the name and email you already pass:

{% code overflow="wrap" %}
```html
<script>
  window.chatWidgetSettings = {
    visitor: {
      id: "12345",
      hash: "3f2a…e91c",
      name: "Maria",
      email: "maria@example.com"
    }
  };
</script>
<script src="https://api.dmchamp.com/v1/chat-widget/CONFIG_ID"></script>
```
{% endcode %}

The inline embed takes the same value as `data-visitor-hash` on the `<div>`, and `window.chatWidget.setVisitor({ visitor: { id, hash } })` works for apps that sign people in without a page reload.

What happens once the signature checks out:

- The customer's chat is stored under their account rather than under the browser, so it is the same conversation on every device and every browser where they are signed in, and one contact in your inbox.
- Their earlier messages load on the new device, and the AI carries on from where they left off.
- If the signature is wrong, the widget quietly behaves as it did before, as a normal per-browser chat, and prints the reason in the browser console so a developer can spot it. Your visitors never see an error.
- The ID is compared exactly as you sent it, so sign the same value you pass as `id`, and use the same ID for the same person everywhere.

Two things to know:

- **Regenerate** in the Manage panel gives you a new secret. Pages still signing with the old one fall back to normal per-browser chats until your server uses the new secret. Existing conversations are kept; they are tied to the customer's ID, not to the secret.
- A conversation someone had before signing in, as an anonymous visitor, stays a separate chat. The account-based conversation starts with the first message they send while signed in.

### Change the Widget Settings from Your Own Code (API)

Everything on the widget's **Manage** panel can also be changed over the [REST API](../api/reference.md), which is handy if you manage many websites or want the attachment button switched off automatically for a client. Send a `PATCH` to `https://api.dmchamp.com/v1/chat-widget-configs/CONFIG_ID` with your API key and only the fields you want to change — for example `{"show_upload_button": false}` hides the attachment button, `{"show_emoji_button": false}` hides the emoji picker, and `{"launcher_icon": "chat-dots"}` swaps the launcher icon. `CONFIG_ID` is the same identifier as in your embed script. The full list of accepted fields (name, opening message, colours, launcher icon, allowed domains, visitor info form, privacy notice, theme, corner and font style) is in the [API Reference](../api/reference.md) under **Chat Widget**. Websites pick the change up the next time the page loads.

### What to Expect After Installation

Once you've added the script to your website, the chat widget will automatically create a chat button in the corner of your website (bottom-right by default). The widget remains in a fixed position as users scroll through your pages, ensuring it's always accessible.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-live-bubble-closed.png" alt="The floating chat bubble in the bottom-right corner of a live website, before a visitor has clicked it"><figcaption><p>This is what visitors see on your site before they open the chat — just the floating button, positioned per your Appearance settings.</p></figcaption></figure>
:::

When visitors click this button, it expands into a full chat window where they can start a conversation, showing your opening message. If Collect visitor info is on, a small form appears first asking for their name and email (and optionally phone) before they can type.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-live-panel-open.png" alt="The opened chat panel showing the opening message in the background and the Before we start lead-capture form (First name, Email, Phone) in front of it"><figcaption><p>The opened chat panel. Here Collect visitor info is on, so the "Before we start..." form appears over the conversation — visitors fill it in once, then chat normally.</p></figcaption></figure>
:::

The chat interface adapts automatically to different screen sizes, so it works seamlessly on both desktop and mobile devices.

### Testing Your Implementation

After adding the widget to your site, test that it works:

1. Open your website in a browser.
2. Click the chat button to open the widget.
3. Send a test message and confirm you get a reply.
4. Repeat on a different device or browser to confirm it works everywhere.

::: master-only
<figure><img src="../.gitbook/assets/v2-chat-widget-live-conversation.png" alt="The chat panel after a visitor sends a test message, showing their outgoing message bubble underneath the opening message"><figcaption><p>After sending a message, it appears as an outgoing bubble in the thread — your AI or team replies in the same window.</p></figcaption></figure>
:::

If the chat widget doesn't appear on your site, check these:

1. Make sure you replaced `CONFIG_ID` with your actual configuration identifier.
2. Make sure the script tag is placed before the closing `</body>` tag.
3. Check the code for typing errors.

### Behind a Corporate Firewall

If the widget loads for the public but not for staff on the office network, the network is almost certainly blocking the domain it loads from. Ask your IT team to allow, over normal HTTPS on port 443:

- **The domain in your embed snippet** — the address in the `<script src="...">` line you copied from the Manage panel.
- **`api.youraiconnector.com`** — the widget also sends its messages here.

Nothing else needs opening: no extra ports and no inbound rules. If the widget still doesn't appear after that, open your browser's developer console on the page and send us what it reports — a blocked request names the domain that was refused, which is usually the whole answer.
