Control the chat from your website
The embed snippet gets a chat bubble onto your site with no code. This page is for the next step: making the chat respond to your site — opening it from your own “Talk to us” button, sending an event to your analytics when someone starts a conversation, moving the launcher on one page, or showing the whole thing in Spanish.
Everything here is optional. If you paste the snippet and change nothing, your widget keeps working exactly as it does today.
The snippet
Section titled “The snippet”The embed snippet from your widget’s settings page is all you need:
<script src="https://app.loquent.io/api/widget/embed.js" data-widget="wid_your_widget_id" async></script>Once it loads, the widget is available on the page as window.Loquent.
Open the chat from your own button
Section titled “Open the chat from your own button”The most common request, and the reason the rest of this page exists. Give your button a click handler:
<button id="chat-button">Talk to us</button>
<script> document.getElementById('chat-button').addEventListener('click', function () { Loquent.push(['open']); });</script>That’s it. open reveals the panel, close hides it, and toggle flips it.
(You can write onclick="Loquent.push(['open'])" directly on the button instead, but
that needs your site to allow inline scripts — the version above works everywhere.)
Why Loquent.push([...]) and not Loquent.open()
Section titled “Why Loquent.push([...]) and not Loquent.open()”Both work — but push works earlier.
Because the snippet is async, your page is usually interactive before the widget has
finished loading. A visitor who clicks your button in that window would hit
Loquent.open() before open exists, and nothing would happen. push solves that:
calls made before the widget loads are queued and replayed in order the moment it’s
ready, and after it’s ready they run immediately.
So push is safe everywhere, which makes it the form worth standardising on. Use
Loquent.open() directly only when you already know the widget is ready — inside a
ready handler, for instance.
Methods
Section titled “Methods”| Call | Does |
|---|---|
Loquent.push(['open']) |
Opens the chat panel. Already open → nothing happens. |
Loquent.push(['close']) |
Closes it, returning keyboard focus to the launcher — or to whatever opened it, if the launcher is hidden. |
Loquent.push(['toggle']) |
Opens if closed, closes if open. |
Loquent.push(['sendMessage', 'I need a quote']) |
Sends that text as the visitor. Opens the chat first, so they can see it, and leaves anything they were typing untouched. |
Loquent.push(['setLocale', 'es']) |
Switches every label in the widget to that language. |
Loquent.push(['setStrings', { … }]) |
Overrides individual pieces of text. See Change the wording. |
Loquent.push(['configure', { … }]) |
Sets any of the settings below from code. Must run before the chat loads — see Which setting wins. |
Loquent.on('opened', fn) |
Runs fn whenever the chat opens. See Events. |
Loquent.off('opened', fn) |
Stops that handler running. |
Loquent.destroy() |
Removes the widget completely — its connection, its timers, and everything it put on the page. |
Loquent.get('wid_…') |
A handle on that widget, carrying the same methods, for pages with more than one. |
Called before the widget is ready, open / close / toggle / sendMessage /
setLocale / setStrings are queued when you use push. Everything else runs straight
away.
Events
Section titled “Events”Subscribe to what happens in the chat:
Loquent.on('conversation:started', function () { // your own analytics, a conversion pixel, anything console.log('a visitor started chatting');});| Event | Fires when |
|---|---|
ready |
The widget has loaded and everything on this page works. Available through Loquent.on only — and it still fires if you subscribe late. |
opened |
The panel opened — by a visitor, by your button, or by auto-open. |
closed |
The panel closed. |
conversation:started |
The visitor sent their first message this session. |
message:sent |
The visitor sent a message. Payload carries first: true on the first one. |
message:received |
A reply arrived. Payload carries role. |
contact:identified |
The visitor gave their details. Payload carries fields — which details, e.g. ['name','email']. |
You can register as many handlers per event as you like, and a handler that throws won’t break the chat or stop the other handlers.
From inside an iframe
Section titled “From inside an iframe”If your site embeds our widget inside an iframe, every event is also posted to the parent frame, so you can listen from outside:
var chatFrame = document.getElementById('your-iframe');
window.addEventListener('message', function (e) { // Check the sender first — anything on the page, or any other frame, can post a // message that looks like ours. if (e.source !== chatFrame.contentWindow) return; if (e.data && e.data.type === 'loquent:event') { console.log(e.data.event, e.data); }});Google Tag Manager
Section titled “Google Tag Manager”Add data-gtm="true" to the snippet and every event is also pushed to dataLayer, named
loquent_ + the event with underscores — conversation:started becomes
loquent_conversation_started.
<script src="https://app.loquent.io/api/widget/embed.js" data-widget="wid_your_widget_id" data-gtm="true" async></script>It’s off unless you ask for it, and it does nothing at all if GTM isn’t on the page — we
never create dataLayer ourselves.
Per-page overrides
Section titled “Per-page overrides”Your widget’s settings in Loquent apply to every page. When one page needs something different — a pricing page with its own sticky button in the corner — set it on the snippet for that page:
<script src="https://app.loquent.io/api/widget/embed.js" data-widget="wid_your_widget_id" data-position="bottom-left" data-offset-y="88" data-theme="light" data-locale="es" data-auto-open="12000" async></script>| Attribute | Values | Does |
|---|---|---|
data-position |
bottom-right, bottom-left |
Which corner the launcher sits in. |
data-offset-x / data-offset-y |
0–400 (pixels) |
Moves the launcher in from the corner, to clear a cookie banner or a back-to-top button. Defaults to 20. |
data-theme |
light, dark, auto |
Locks the colour scheme. auto (the default) follows the visitor’s device. |
data-locale |
en, es |
Which language to render in. |
data-auto-open |
milliseconds | Opens the chat by itself after that long — once per visit, and never on a phone (where it would take over the whole screen). Leave it off unless you mean it. |
data-hide-on-mobile |
true, false |
Hides the launcher on phones. The controls above still work, so you can open the chat from your own button. |
data-z-index |
a number | Raises the widget above a stubborn overlay on your page. |
data-gtm |
true, false |
The GTM bridge above. Off by default. |
Which setting wins
Section titled “Which setting wins”From most specific to least:
-
configure()from your code — the most specific, and the only one you can compute at runtime. -
A
data-*attribute — this page’s snippet. -
Your widget settings in Loquent — the default for every page.
-
Our built-in default.
Nearest to the page wins. A value we don’t understand is ignored and the next level down applies, so a typo in your HTML can never stop the chat from loading — check the browser console and you’ll find a note naming it.
configure() is read when the chat mounts, so it has to run before the embed script
finishes loading — which is exactly what the queue is for:
<script> window.Loquent = window.Loquent || []; // e.g. move the launcher only for signed-in visitors if (document.body.dataset.signedIn) { Loquent.push(['configure', { position: 'bottom-left', offsetY: 96 }]); }</script><script src="https://app.loquent.io/api/widget/embed.js" data-widget="wid_your_widget_id" async></script>Call it after the chat has loaded and it won’t take effect — use setLocale() /
setStrings() for live changes. You’ll get a note in the console if you do.
Change the language
Section titled “Change the language”The whole widget ships in English and Spanish. It picks a language automatically:
data-locale, then the visitor’s own browser, then English. There is no
language setting on the widget itself — the snippet and the visitor decide.
So a Spanish-speaking visitor already gets a Spanish chat box with no work from you. Force
it for one page with data-locale="es", or switch it live:
Loquent.push(['setLocale', 'es']);An unknown language falls back to English rather than showing anything broken.
Change the wording
Section titled “Change the wording”To change individual text without translating everything, override the pieces you care about:
Loquent.push(['setStrings', { 'form.heading': 'Before we begin', 'form.submit': 'Start chatting', 'composer.placeholder': 'Ask us anything…', 'empty.text': 'Send a message to get started', 'header.subtitle': 'Usually replies instantly',}]);Anything you don’t override keeps its translation, and your overrides stick even if the language changes afterwards — what your page said is more specific than our table.
Recipes
Section titled “Recipes”Open the chat from a link anywhere on the page
Section titled “Open the chat from a link anywhere on the page”<a href="#" id="chat-link">Chat with us</a><script> document.getElementById('chat-link').addEventListener('click', function (e) { e.preventDefault(); Loquent.push(['open']); });</script>Ask a question on the visitor’s behalf
Section titled “Ask a question on the visitor’s behalf”Useful on a pricing page — open the chat with the question already asked:
<button id="ask-pro">Ask about Pro</button><script> document.getElementById('ask-pro').addEventListener('click', function () { Loquent.push(['sendMessage', 'What does the Pro plan include?']); });</script>sendMessage opens the chat itself, so the visitor sees what was asked on their behalf.
Fire a conversion when someone starts chatting
Section titled “Fire a conversion when someone starts chatting”Loquent.on('conversation:started', function () { gtag('event', 'chat_started'); // or your own analytics});Move the launcher out from behind a cookie banner
Section titled “Move the launcher out from behind a cookie banner”<script src="https://app.loquent.io/api/widget/embed.js" data-widget="wid_your_widget_id" data-offset-y="120" async></script>A Spanish site with your own wording
Section titled “A Spanish site with your own wording”<script src="https://app.loquent.io/api/widget/embed.js" data-widget="wid_your_widget_id" data-locale="es" async></script><script> Loquent.push(['setStrings', { 'header.subtitle': 'Respondemos al instante' }]);</script>Troubleshooting
Section titled “Troubleshooting”My button does nothing. Use Loquent.push(['open']) rather than Loquent.open() —
your click is probably landing before the widget has loaded.
A data-* attribute is being ignored. Open the browser console. An unrecognised
attribute name or an out-of-range value is reported there by name.
The widget is behind something on my page. Raise data-z-index.
Nothing works and the console says the widget is missing. Check data-widget matches
the id on your widget’s settings page, and that the widget is Enabled.
New to the widget? Start with Add chat to your website. Every conversation lands in Messaging, where drafts, approvals, and escalations decide how much your AI teammate handles on its own.