For the complete documentation index, see llms.txt. This page is also available as Markdown.

Widget recipes

Copy-paste patterns for common widget customisations.

Working patterns you can paste. All of them assume the widget is installed — see Install with JavaScript.

Each wraps its work in the ready event, which is the safe place for API calls.

Your own button, no floating launcher

<button type="button" id="cta">Talk to us</button>

<script>
window.LimeCall && window.LimeCall.on("ready", function () {
  window.LimeCall.hideLauncher();
  document.getElementById("cta").addEventListener("click", function () {
    window.LimeCall.open();
  });
});
</script>

Open straight onto a specific tab

document.getElementById("msg-us").addEventListener("click", function () {
  window.LimeCall.openTab("message");
});

Link to #limecall — no JavaScript at all:

#lc-open and #lc-widget work the same way, and the anchor survives a cross-page link (/pricing#limecall), which makes it the one to use in emails and ads.

For a link the visitor may click more than once, handle the click instead — a repeated identical anchor fires no event:

Show the widget only on high-intent pages

Display rules in the dashboard are the better tool for this — see Display rules. When you need logic they cannot express:

Open automatically for an engaged visitor

The widget scores engagement and reports it. Rather than a fixed timer, wait until someone is actually engaged:

Send conversions to Google Analytics

Send conversions to Meta

Log failures you would otherwise never see

Worth doing early. Failed requests are invisible otherwise, and a run of rejected usually means your business hours are wrong.

React to a browser call starting and ending

Do not offer a call when the widget is hidden

Only promise a call someone can take

state.visible tells you the widget is on the page. hasAvailableAgents() tells you somebody would actually answer — closed hours, an empty team, or exhausted AI minutes all come back false.

Swapping the wording beats hiding the button. The visitor who wanted to talk still gets a way through.

Route by page, without asking the visitor

Checking against getDepartments() first means renaming a department in the dashboard degrades to your default routing instead of sending a mismatched label.

Submit from your own form and keep the result

Full version, including keeping your own backend in the loop: Connect your own form.

Clean up in a single-page app

Handlers persist across client-side navigation, so remove the ones tied to a page:

Registering the same handler twice is safe — it is only added once — but a handler belonging to a page the visitor has left will still fire.

Was this helpful?