Chat9

Embedding the Widget

How to add the Chat9 chat widget to your site, with optional userHints for personalization.

Basic embed

Paste this snippet before the closing </body> tag:

<script src="https://widget.getchat9.live/widget.js" data-bot-id="YOUR_BOT_PUBLIC_ID"></script>
<script>
  Chat9Widget.start();
</script>

data-bot-id is your bot's public ID — safe to include in page HTML.

Loading widget.js registers window.Chat9Widget but does not mount any UI. You explicitly start the widget with Chat9Widget.start(config?) — call it with no arguments for an anonymous widget with default styling, or pass an options object to customize.

Do not add async or defer to the widget.js tag — the loader reads document.currentScript synchronously and will not register without it.

Configuration

All options are arguments to Chat9Widget.start():

<script src="https://widget.getchat9.live/widget.js" data-bot-id="YOUR_BOT_PUBLIC_ID"></script>
<script>
  Chat9Widget.start({
    mode: "bubble",          // "bubble" | "inline"
    color: "#a855f7",
    position: "right",       // "right" | "left"
    target: "chat9-widget",  // inline mode only — id of the host element
    userHints: {
      name: "Anna",
      email: "anna@example.com",
      locale: "ru-RU"
    }
  });
</script>
FieldDefaultNotes
mode"bubble""bubble" or "inline"
targetDOM element id for inline mode
colorviolet gradientBubble background color (#RGB, #RRGGBB)
position"right""right" or "left"
topClearance0px reserved at the viewport top (e.g. height of a fixed navbar)
userHintsSee userHints

Modes:

  • Bubble — floating button, bottom corner of the page.
  • Inline — renders inside a container you provide. Add <div id="chat9-widget"></div> where you want the widget.

Routing from Russia

If your site primarily serves visitors in Russia, load the widget from the Russian edge proxy. Replace widget.getchat9.live with widget-ru.getchat9.live in the script src — both the widget bundle and the API origin route through it automatically:

<script src="https://widget-ru.getchat9.live/widget.js" data-bot-id="YOUR_BOT_PUBLIC_ID"></script>
<script>
  Chat9Widget.start();
</script>

This bypasses traffic throttling that some Russian ISPs apply to Vercel/Railway. Visitors outside Russia work the same way — they just hit the RU edge with a small extra hop. If you serve mixed audiences, detect the visitor's country server-side and emit a different src per request, or A/B test.

CSP

If your site uses a Content Security Policy, default origins:

script-src  https://widget.getchat9.live;
frame-src   https://widget.getchat9.live;
connect-src https://getchat9.live;

If you load the widget from the Russian edge proxy (widget-ru.getchat9.live), allow these origins instead:

script-src  https://widget-ru.getchat9.live;
frame-src   https://widget-ru.getchat9.live;
connect-src https://api-ru.getchat9.live;

Where to get the embed code

  1. Log in to your Dashboard at https://getchat9.live.
  2. Copy the embed block from the Dashboard home or the Embed page.

Lifecycle API

window.Chat9Widget exposes an explicit lifecycle. The script downloads once; you control when the chat appears, when it goes away, and what identity it carries.

MethodBehavior
Chat9Widget.start(config?)Mount the FAB and chat iframe. No-op (with a console warning) if already started — call stop() first to reconfigure.
Chat9Widget.stop()Unmount the DOM and listeners. window.Chat9Widget stays registered; the script does not re-download. Call start() again to bring it back.
Chat9Widget.setHints(hints | null)Push a new identity into a running widget. If the widget is stopped, the hints are remembered for the next start(). Pass null to clear (anonymous).
Chat9Widget.isStarted()true while the widget is mounted.
Chat9Widget.destroy()Terminal teardown. Removes the DOM and deletes window.Chat9Widget. To use the widget again on this page you must reload widget.js. Most consumers want stop() instead.

Session continuity

Conversation history is stored on the server. The widget keeps a session_id in the visitor's browser (localStorage) for up to 24 hours — on return visits it fetches the previous conversation from the server using that ID, so history persists across page reloads.

When userHints includes user_id or email, the storage key is scoped per visitor — different users on the same device get separate sessions.

Cross-device resume is not supported: the session_id lives in the local browser only.

When the bot escalates a conversation to a human agent, the chat is marked as ended. The transcript stays visible; a "Start new chat" button appears for the visitor to open a new session.

Greeting is shown once per new session and not repeated on resume.

Clarification: the bot may ask one follow-up question when a request is ambiguous. It appears as part of the normal text reply.

Login / logout in single-page apps

Because start, stop, and setHints are explicit, the widget can survive a full SPA login/logout cycle without reloading widget.js.

// At app startup, mount the widget anonymously:
Chat9Widget.start({ color: "#a855f7" });
 
// Once the user logs in:
Chat9Widget.setHints({
  user_id: user.id,
  email: user.email,
  name: user.name
});
 
// User switches accounts without reloading:
Chat9Widget.setHints({ user_id: otherUser.id, email: otherUser.email });
// Conversation state resets server-side — the previous user's chat does
// not leak to the new identity.
 
// Logout — pick one:
Chat9Widget.setHints(null);   // keep the widget visible, anonymous
// or
Chat9Widget.stop();           // hide the widget completely
 
// Re-login after stop():
Chat9Widget.start({
  color: "#a855f7",
  userHints: { user_id: user.id, email: user.email }
});

Substitute your own brand color in color (any #RGB/#RRGGBB) — or omit it for the default violet gradient. All other options listed in Configuration are supported here too.

setHints() updates a running widget in-place — you do not need to stop and start to change identity.

For server-rendered or multi-page apps, the simplest pattern is to render the embed snippet on every page and pass the right userHints per request. On logout the page navigates and the widget is recreated naturally.


userHints

By default the widget is anonymous. Pass userHints to personalize the session — either at start() time, or later via setHints():

<script src="https://widget.getchat9.live/widget.js" data-bot-id="YOUR_BOT_PUBLIC_ID"></script>
<script>
  Chat9Widget.start({
    userHints: {
      user_id: "42",
      name: "Anna",
      email: "anna@example.com",
      locale: "ru-RU",
      plan_tier: "pro"
    }
  });
</script>

Hints are used for greeting personalization, language selection, and escalation email metadata.

Note: Hints come from the browser and can be modified by anyone. Do not use them for access control, paid-tier gating, or audit logs. Treat them as personalization suggestions only.

Fields

FieldNotes
user_idStable ID from your system. Primary key for session grouping. Falls back to hint:<email> if absent.
emailUsed in escalation notifications. Malformed values are dropped.
nameDisplay name.
plan_tier"free", "starter", "growth", "pro", "enterprise". Affects escalation priority.
audience_tagFree-form segment label.
localeBCP-47 (e.g. "en-US", "ru-RU"). Overrides browser locale for language selection.

Escalation priority

TriggerOther tiers / None"pro" or "enterprise"
User requests a humanHighCritical
No relevant answer foundMediumHigh
Answer rejected by quality checkMediumMedium

On this page