Testing & debugging
How to test widget code, and what to check when something does not work.
Test in a private window
A normal window may serve a cached page and may remember the widget was dismissed. Nearly every "it stopped working" report resolves here.
Check the widget actually loaded
In the browser console:
window.LimeCall && window.LimeCall.versionundefined means the script has not loaded — a snippet problem, not an API problem. See The widget is not showing.
Check its state
window.LimeCall.getState()
// { ready: true, open: false, mode: "bubble", inWebCall: false, tab: null, visible: true }visible: false means a display rule has hidden the widget on this page. ready: false means it is still initialising.
Watch every event at once
The fastest way to see what the widget is doing:
["ready","open","close","tab","teaser","score",
"callback:requested","callback:failed","message:sent",
"webcall:started","webcall:ended"].forEach(function (ev) {
window.LimeCall.on(ev, function (payload) {
console.log("[LimeCall]", ev, payload);
});
});Paste that, then use the widget normally. It answers most "why did nothing happen" questions in one pass.
Do not trust the return value
Methods return false when the widget is not ready yet — but the call is still queued and replayed, up to 8 of them. A false is not a failure, and true is not a delivered callback.
For anything that matters, use the events — or requestCallback(), whose promise does resolve with the real outcome.
Check whether anyone can answer
false has several causes, and the method deliberately does not tell you which: outside working hours, nobody configured to route to, or no AI minutes left. To find out which one applies, open the Network tab and look at the response from callback/availability — it carries a reason:
reason
Means
outside_hours
Working hours say closed.
nobody_configured
The widget routes to a person or team that no longer resolves.
no_ai_minutes
AI minutes are exhausted and no overflow person is configured.
overflow
Out of AI minutes, but a human answers — this one is paired with available: true.
Remember the 20-second cache: after changing your hours or routing, wait it out, or reload the page, before re-testing.
getDepartments() returns an empty array
You called it too early. Departments arrive with the widget's configuration, so the array is empty until ready fires. Move the call inside on("ready", …).
setDepartment() seems to be ignored
Two things override it, both intentionally:
The visitor's own choice. If they pick a department in the form, theirs wins.
A label that does not match. Compare against
getDepartments()— the names must match exactly, and renaming a department in the dashboard breaks a hard-coded string.
The #limecall link does nothing the second time
The anchor opens the widget on load and whenever the address changes. Clicking a link to the address you are already at changes nothing, so the browser fires no event. Use a click handler calling open() for a control the visitor may use repeatedly.
A setting changes in the dashboard but not on your site
Check your page source for data- attributes beyond data-key and data-api.
Attributes override the fetched configuration and freeze that setting permanently. A snippet carrying data-mode="bubble" ignores every later change to Display style.
The widget loads but calls never connect
That is routing, not the widget. Work through Calls are not connecting — the usual causes are business hours, personal hours, or no destination configured.
Requests are rejected
Listen for callback:failed and read e.message. reason: "rejected" is a deliberate refusal — closed hours, blocked number, unsupported country. reason: "network" is connectivity.
Content Security Policy
A blocked script fails silently except for a console violation. Allow the host from your snippet in both directives:
Testing on a local machine
The widget works on localhost. If you restrict by URL, remember your display rules apply to the local URL too — a rule matching your production path will hide the widget locally.
Getting help
Include the page URL, the browser, the output of getState(), and any console errors. Those four turn a multi-day exchange into one reply.
Was this helpful?