1. The line
Immediately before the closing </body> tag, on every page. Replace
be_YOUR_KEY with the business's key from its Belline dashboard.
<script src="https://app.belline.ai/embed.js" data-belline="be_YOUR_KEY" data-mode="both" async></script>2. Float her where you want
Bottom left, 32 pixels from the side and 96 from the bottom (above a cookie bar):
<script src="https://app.belline.ai/embed.js" data-belline="be_YOUR_KEY" data-mode="both" data-side="left" data-offset-x="32" data-offset-y="96" async></script>In the middle of the bottom edge, at the large size:
<script src="https://app.belline.ai/embed.js" data-belline="be_YOUR_KEY" data-mode="both" data-side="center" data-size="large" async></script>Values are checked and clamped rather than trusted: an offset never takes her off the screen, and a value that is not a number is ignored with a warning in the console. On a phone the chat still opens as a sheet over the page, and a call still opens over it.
| Attribute | Default | Values | What it does |
|---|---|---|---|
data-side |
right |
right · left · center |
Where along the bottom of the page the buttons float: a corner, or the middle. Useful when something else — a cookie bar, a live-chat widget, a back-to-top arrow — already occupies the right. Set here it wins over the corner chosen in the dashboard. With data-mount it says where in the element Belle sits instead (the middle when unset). |
data-offset-x |
24 (18 on a phone) |
— | Pixels from the side the buttons float on, from 0 to 400. A larger number is clamped, and the widget never goes further than the screen allows. Ignored with data-side="center" and with data-mount. |
data-offset-y |
24 (18 on a phone) |
— | Pixels from the bottom of the screen, from 0 to 600, to sit above a cookie bar or a sticky footer. Wins over the height chosen in the dashboard. Ignored with data-mount. |
data-size |
standard |
small · standard · large · a number of pixels |
The size of the round button (48, 58 or 68 pixels; a number is clamped to 40–96), or of Belle's face where the business has video (200, 260 or 320; a number is clamped to 120–360). Buttons with words on them keep their text size. Wins over the size chosen in the dashboard. |
data-mount |
— |
— | A CSS selector, such as #belle. Belle is drawn inside that element, in the page's own flow, instead of floating in a corner — the way belline.ai shows her in its first screen. If nothing on the page matches, she floats in the corner instead and the script writes one warning to the console. Chats and calls still open in their own window over the page. |
The dashboard's own corner, size and height stay the defaults for every page. An attribute on one page's line wins on that page.
3. Inside a section of the page
Put an element where she belongs and name it in data-mount. She is drawn inside it, in
the page's flow, never wider than it, and she scrolls with the page. Chats and calls still open in their
own window over the page.
<section class="hero">
<h1>Ask us anything</h1>
<div id="belle" style="min-height:400px"></div>
</section>
<script src="https://app.belline.ai/embed.js" data-belline="be_YOUR_KEY" data-mode="both" data-mount="#belle" async></script>Her details arrive from Belline a moment after the page paints, so give the element the height she
will take and nothing moves when she lands: min-height:400px where the business has video
(her face, the label above it and the buttons under it), and about 60 pixels per button otherwise:
<div id="belle" style="min-height:124px"></div>If nothing on the page matches the selector, she floats in the corner instead and the console says why, once.
4. Open her from your own buttons
Any element with data-belline-open opens her when it is clicked. No script, so it works
on a page with a strict Content-Security-Policy:
<button type="button" data-belline-open="chat">Chat with us</button>
<button type="button" data-belline-open="voice">Talk to us</button>
<a href="#" data-belline-open="video">Video call</a>
<a href="#" data-belline-open>Ask Belle</a>Or from your own script, through window.Belline. If your code might run before the line
above has loaded, paste the one-line stub first; calls made before then are queued and run in order once
it arrives:
<script>window.Belline=window.Belline||{q:[]};["open","close","toggle","on","off","mount"].forEach(function(m){Belline[m]=Belline[m]||function(){Belline.q.push([m].concat([].slice.call(arguments)))}});</script>
<script>
// Safe to call before embed.js has loaded: the calls wait in Belline.q.
document.querySelector("#book").addEventListener("click", function () {
Belline.open("chat");
});
</script>| Call | What it does |
|---|---|
Belline.open(kind) | Opens "chat", "voice" or "video"; with no kind, the business's main one. Returns false and writes a console warning for something this business does not offer here. |
Belline.close() | Closes whatever is open, ending a call. |
Belline.toggle(kind) | Closes her if she is open, otherwise opens kind. |
Belline.on(event, fn) | Calls fn on open, close, call-start, call-end or message. |
Belline.off(event, fn) | Stops calling fn; with no fn, stops every handler for that event. |
Belline.mount(target) | Moves her into an element (a selector or the element itself), as data-mount does; Belline.mount(null) floats her again. Refused while a chat or call is open, because moving it would drop it. |
window.BellineVideo, the video bubble's own script, is unchanged.
5. Listen for what she does
<script>
Belline.on("open", function (e) { console.log("opened", e.kind); }); // chat | voice | video
Belline.on("close", function (e) { console.log("closed", e.kind); });
Belline.on("call-start", function (e) { console.log("call window open", e.kind); }); // voice | video
Belline.on("call-end", function (e) { console.log("call window closed", e.kind); });
Belline.on("message", function (e) { console.log("a message from", e.from); }); // visitor | reply
</script>call-start and call-end mean the call's window opened and closed.
message fires for each message that appears in the chat window and says only who it was
from, the visitor or the business: never the words. The API sends Belline nothing of its own: opening
her does exactly what a visitor's tap on her button does, and the events only tell your page.
6. Which page she is on
When a visitor opens the chat, or starts a call or a video call, the line tells Belle which page of your site they are on, so
"how much is this one?" on a page about one service is answered about that service. She is told three
things: the page's address, its title, and its main headings (h1 and h2). That
is all. She does not read the rest of the page, and she is never sent anything a visitor types into your
site, cookies or anything your page has stored.
Before it reaches her, Belline takes out the part of the address after the ? (except a
few words such as lang or tab), anything that looks like an email address or a
long number, and anything over a small size limit. Belline uses it for her reply and does not store it. A heading
inside a form is skipped, and so is anything inside an element you mark
data-belline-private:
<h2 data-belline-private>Welcome back, Sara</h2>To switch it off for the whole site: Channels, Website chat, Which page the visitor is on, Don't tell Belle.
7. Instructions for AI site builders
Copy this into your instructions, or follow it as written.
Instructions for AI site builders (Belline)
1. Use the line the business's Belline account gives you: the dashboard
(Channels -> Website) or GET https://app.belline.ai/api/install/v1/venue/snippet.
Never invent a key, and never copy embed.js to the site or load it from
anywhere but https://app.belline.ai.
2. Paste it once, immediately before </body>, on every page.
3. Floating (the default): choose with data-side="left|right|center",
data-offset-x / data-offset-y (pixels) and data-size
(small|standard|large or pixels). Leave them out to use what the business
chose in its dashboard.
4. In a section: put <div id="belle" style="min-height:400px"></div> where she
belongs and add data-mount="#belle" to the line. 400px holds her face
where the business has video; about 60px per button holds the buttons.
5. Your own buttons: give them data-belline-open="chat", "voice" or "video"
(empty for the business's main one). No script is needed.
6. From script: Belline.open(kind), close(), toggle(kind), on(event, fn),
off(event, fn), mount(selectorOrElement). Paste the one-line stub first if
your code may run before embed.js has loaded.
7. The page chooses among what the business offers. It cannot switch chat,
voice or video on: Belline.open() for something not offered writes a
warning in the console and does nothing.
8. Add the live domain to the business's allowed websites, or the widget
takes itself off the page.
9. Belline.on("message") says who spoke, never what was said. Do not try to
read the conversation from the page.
10. Restyle nothing with !important. The attributes above and the CSS
variables --belline-lift, --belline-inset and --belline-size are the
supported way to move and size her.Machine-readable summary of this site: /llms.txt. A Markdown copy of this page: /developers.md.