Developers

Widget JavaScript API

The tag, the window.SupportFast object, the options, the events, the CSS variables and the technical limits of the widget, for whoever develops the website.

View as Markdown

To install the widget without writing code, start from Installing the widget.

#What stays stable across versions

These elements don't change name or meaning from one version to the next:

  • The chatbot.js file, included as a classic script, with id="supportfast-script" (or id="chatbot-script") and the data-chatbot-id attribute.
  • The window.SupportFast object, with init() and version.
  • window.ChatbotConfig.lang and window.chatbotUserData.
  • The chatbot_open event in the dataLayer.
  • The #chat-widget-container container, which the CSS variables apply to.
  • The CSS variables --sf-offset-bottom, --sf-offset-side and --sf-z-index.

Everything else, including the widget's internal classes, can change: don't use it in your website's code.

#The tag

HTML · the widget tag (sample agent code)

<script defer id="supportfast-script" src="https://cdn.supportfast.ai/chatbot.js" data-chatbot-id="bot-a1b2c3d4e5"></script>
AttributeValueNotes
idsupportfast-script or chatbot-scriptRequired. Keep the one in the code the console gives you.
srcThe address of chatbot.jsRequired. Don't host the file on your own server: the widget loads its parts from the same folder.
data-chatbot-idThe agent's codeRequired. Without it, the widget doesn't start.
defer—Recommended, and already in the console's code. The widget also works with async or with neither, but your code must wait for it as explained further down.
  • The tag must stay a classic script: don't add type="module".
  • Include it once per page. A second inclusion does nothing.
  • The widget mounts when the document is ready. If the tag arrives later, for example from Google Tag Manager, it mounts right away.

#The window.SupportFast object

The widget creates window.SupportFast as soon as chatbot.js runs, before the chat is ready.

MemberWhat it does
versionThe version of the widget running on the page.
init()Mounts the widget, if it isn't mounted already. It runs on its own when the document is ready; calling it again doesn't create duplicates. If your framework removed the container, it mounts it again.
open(), close(), toggle()Open, close or toggle the chat.
identify(data)Replaces the signed-in customer's data. Without arguments, it reads window.chatbotUserData again.
on(event, handler), off(event, handler)Start or stop listening to the ready, open and close events.
  • Calls made after chatbot.js runs, but before the chat is ready, are queued and run in the order they arrive.
  • ready fires when the agent is loaded and active; a handler registered later runs right away. If the agent isn't available, it doesn't fire.

HTML · a website button that opens the chat

<button type="button" onclick="window.SupportFast && window.SupportFast.open()">Contact us</button>

#Making your code wait

Before chatbot.js runs, window.SupportFast doesn't exist and there's no queue to leave calls in. So your code must wait for the object.

  • With the tag in defer, as in the console's code, the DOMContentLoaded event is enough: it fires after defer scripts have run.
  • With async, with Google Tag Manager or with a plugin that delays scripts, chatbot.js can arrive after DOMContentLoaded. Use the function below, which works in every case.

JavaScript · waiting for the widget, however it's loaded

function conSupportFast(azione) {
  var tentativi = 0;
  (function prova() {
    if (window.SupportFast && typeof window.SupportFast.on === "function") {
      azione(window.SupportFast);
    } else if (tentativi < 100) {
      tentativi += 1;
      setTimeout(prova, 100); // retries every tenth of a second, for 10 seconds
    }
  })();
}

conSupportFast(function (chat) {
  chat.on("ready", function () {
    // the chat is loaded and the agent is active
  });
});

If chatbot.js can arrive later, for example because a plugin waits for the visitor's first interaction, raise the number of attempts.

#Forcing the language: window.ChatbotConfig.lang

Normally the widget picks the language from the visitor's browser, among the workspace languages. To force it, set window.ChatbotConfig before the widget code.

HTML · chat always in English

<script>window.ChatbotConfig = { lang: "en" };</script>
<script defer id="supportfast-script" src="https://cdn.supportfast.ai/chatbot.js" data-chatbot-id="bot-a1b2c3d4e5"></script>
  • Possible codes, in lowercase: it, en, de, fr, es, nl, pl, tr, pt, pt-br, sr. it-IT or IT aren't valid.
  • The language must be one of the workspace languages. Otherwise the widget ignores it and picks as usual.
  • The language is set at startup: to change it, the page must be reloaded.
  • It applies only to the widget installed with the code on the website, not to the link and the iframe.

#The signed-in customer's data: window.chatbotUserData

With window.chatbotUserData you pass the widget the data of a customer signed in to your website. The fields are firstName, lastName, fullName, company, email, phone and metadata, for the workspace variables. Limits and examples are in Passing user data.

#Events for Google Analytics and Tag Manager

Every time the chat opens, the widget runs window.dataLayer.push({ event: "chatbot_open" }). If dataLayer doesn't exist, it creates it. The event has no other parameters.

With Google Tag Manager, create a trigger of type Custom Event, with event name chatbot_open. Connect it to a Google Analytics 4 event tag, for example with the same name. Publish the container, open the chat and look for the event in the Analytics Realtime report.

With gtag.js, without Tag Manager, an entry in the dataLayer doesn't become an Analytics event. Use the widget's open event:

JavaScript · GA4 event when the chat opens

// conSupportFast is the function from "Making your code wait", above
conSupportFast(function (chat) {
  chat.on("open", function () {
    gtag("event", "chatbot_open");
  });
});

The chat inside an iframe communicates with the page that contains it through postMessage messages, listed in Passing user data.

#Moving the button: the CSS variables

The widget container reads three CSS variables, which you can set from the website's stylesheet:

VariableDefaultWhat it changes
--sf-offset-bottom30pxThe button's distance from the bottom of the screen.
--sf-offset-side25pxThe distance from the side, right or left depending on the Button position.
--sf-z-index2147483647The stacking level: the default value is the highest possible.

CSS · button higher up, so it doesn't cover a cookie banner

#chat-widget-container {
  --sf-offset-bottom: 100px; /* the button moves above the banner, about 80 pixels tall */
  --sf-offset-side: 20px;
  --sf-z-index: 1000; /* lower than the default: the banner, if it has a higher level, stays above the chat */
}
  • You can set them on #chat-widget-container or on an element that contains it, such as :root.
  • The open window and the bubble move with the button. Below 600 pixels wide, the open window fills the whole screen anyway.
  • Lower --sf-z-index if an element of the website, such as a menu or the cookie banner, must stay above the chat: every element with a level higher than the value you choose goes on top.
  • To hide the widget on a page, apply the rule #chat-widget-container { display: none; } on that page only. You need it, for example, on the page where you put the chat with the iframe.

#Isolation from the website's CSS

The chat is isolated from the rest of the page: the website's CSS doesn't get into the chat and the chat's CSS doesn't get out. From the website you control only the container and the three CSS variables.

#Content Security Policy

If the website sends a Content Security Policy (CSP), the policy must allow the addresses the widget loads its parts from and communicates with. Otherwise the button doesn't appear, or the chat opens but doesn't answer. Add these origins to the directives the website already uses:

DirectiveOrigins to addWhat it's for
script-srchttps://cdn.supportfast.aichatbot.js and the widget's parts, which come from the same folder.
font-srchttps://cdn.supportfast.aiThe chat's font.
connect-srchttps://server.supportfast.ai and wss://server.supportfast.aiThe agent, the messages, attachment uploads and real-time updates, for example operators' replies.
img-srchttps: and blob:The agent's photo or logo, images in answers, attachments and the preview of a photo before it's sent. Images come from several addresses, temporary ones too: that's why https: is needed.
media-srchttps:Playing voice messages in the chat.
frame-srchttps://app.supportfast.aiOnly if you put the chat on a page with the iframe: it's the address you find in the iframe code.

HTTP · example header with only the widget's directives

Content-Security-Policy:
  script-src 'self' https://cdn.supportfast.ai;
  font-src 'self' https://cdn.supportfast.ai;
  connect-src 'self' https://server.supportfast.ai wss://server.supportfast.ai;
  img-src 'self' https: blob:;
  media-src 'self' https:;
  frame-src 'self' https://app.supportfast.ai
  • The widget needs neither 'unsafe-inline' nor 'unsafe-eval'. The scripts you write in the page yourself, such as window.chatbotUserData or window.ChatbotConfig, are inline scripts instead: with a policy without 'unsafe-inline', give them a nonce or move them to a file.
  • For voice messages, the browser must grant the page access to the microphone. If the website sends the Permissions-Policy header, it must contain microphone=(self). In the iframe, the console's code already has allow="microphone".
  • On a reseller's portal the addresses can be different: for script-src, font-src and frame-src, use the domains you find in the code copied from the console.

How to check. Open the website, then the browser console (F12), and open the chat. If the policy blocks something, the console shows an error naming the directive and the blocked address: add it and try again.

#What it saves in the browser

The widget uses only localStorage: no cookies, no sessionStorage or IndexedDB. With the button, the data is stored on your website's domain; with the link and the iframe, on the chat's domain.

  • The privacy consent given by the visitor is valid until the same day of the following month. A conversation idle for more than 31 days doesn't reopen on its own.
  • The widget's keys start with sf:. If a cookie manager clears localStorage, exclude them: otherwise the chat starts from scratch at every visit.
  • If the browser denies localStorage, the widget works without memory.

#Messages in the browser console

During normal operation the widget doesn't write to the console. When something goes wrong, it writes a message in English that starts with [SupportFast]:

MessageWhat it means
script tag not found: it needs id="supportfast-script" or id="chatbot-script" and a src.The tag doesn't have the right id or the src. Also check that a plugin hasn't removed the id.
data-chatbot-id is missing on the script tag.The agent's code is missing.
the widget could not be loaded.The widget's parts didn't arrive: network, Content Security Policy, or chatbot.js copied to your own server.

Some cases produce no message: agent paused, code that doesn't exist, domain not authorized, browser too old. The causes and fixes are in Website widget.

#Supported browsers

The widget works on Chrome and Edge from version 85, on Firefox from 101 and on Safari from 16.4. On iPhone and iPad it needs iOS or iPadOS 16.4 or later. On older browsers the button doesn't appear, with no effect on the rest of the page.

Voice messages also need a browser that can record audio, and access to the microphone. Where they're missing, the microphone doesn't appear.

#Versions and updates

The tag always points to the same chatbot.js: new versions arrive on their own, without touching the website. To find out which version is running, type window.SupportFast.version in the browser console.

#See also