JavaScript API and events

Control the chat from your page, listen for its events, and pass in what your page knows about the visitor.

JavaScript API#

Everything lives on window.SubcontextWebchat, which exists as soon as the script has loaded.

Starting and stopping#

Method What it does
init(options) Starts the chat. With no options, it reads the script tag's data-* attributes. If a chat is already running, it only puts it back on the page.
enable() Shows a chat that was hidden with disable(), or starts one that was loaded with enabled: false.
disable() Hides the chat and closes its connection, but keeps the options and the conversation.
destroy() Removes the chat completely (stops the microphone, closes the connection). Call init() to start again.
detach() Takes the chat off the page without destroying it. init() puts it back. (Mostly used by Turbo sites.)
version The script's version, for example "1.2.0".

Opening and asking#

Method Returns What it does
open({ expanded }) nothing Opens the panel. expanded: true opens it large. Does nothing in embedded mode.
ask(text, { expanded }) a Promise Opens the chat and sends text as the visitor's message, starting a conversation if needed. Use it for your own "Ask a question" box or quick-question buttons.
startChat() a Promise Starts (or picks up) the conversation without sending anything. Fails with Conversation already starting if one is starting, or No agent available if the agent didn't load.
resetConversation() nothing Ends the current conversation on this browser; the next message starts a new one. Closes the panel. Visitors can do the same by typing /new in the chat.
toggleVoice() a Promise Starts or stops talking in the browser (asks for the microphone the first time). Use it for your own microphone button, mostly in embedded mode.

Context and layout#

Method Returns What it does
setContext({ subcontext }) nothing Replaces (doesn't merge) the page information. It is used when the next conversation starts; a conversation already under way keeps what it started with. Passing a quote form's application_id and application_share_token is the exception. It links the current conversation to that application.
setOpenedFrom('website' or 'quote_form') nothing Changes where the chat counts as opened from. Changing a website chat to 'quote_form' before the visitor has typed swaps in the quote form greeting.
dock(target, { onUndock, openedFrom }) true or false Moves the chat into a box on your page (a CSS selector or an element), for example beside a quote form. The close button then puts it back and calls your onUndock. Returns false in embedded mode, before init(), or if the box isn't found.
undock() nothing Puts a docked chat back in the corner, open or closed as it was.
notifyFormProgress({ stagePosition }) nothing Lets the chat know a quote form on the page has finished a stage, so the chat can acknowledge it if it is open.

Carrying the conversation on elsewhere#

Method Returns What it does
contactMe({ channel, phone_number, email, consent_confirmed, resume_url, idempotencyKey }) a Promise of a result (below) Moves the conversation to another channel. channel is 'sms' (the default), 'whatsapp', 'email' or 'voice' (a phone call back). Works during a chat and before one has started (then the page information goes with it).
whatsappMe({ phone_number, consent_confirmed }) the same A shortcut for contactMe with channel: 'whatsapp'.

The result is one of these:

ts
{ status: 'ok', channel: string, conversation_id?: string, phone_number?: string, email?: string }
{ status: 'consent_withdrawn', phone_number: string, message: string }
{ status: 'unavailable', channel: string, message: string }
  • ok: the request went through. A WhatsApp request can come back with channel: 'sms', which means a text was sent instead.
  • consent_withdrawn: this person asked you before to stop messaging them there. Show them the message, and only if they say yes, call again with consent_confirmed: true.
  • unavailable: the agent has no number for that channel. See the optional extras.

Anything else fails (the Promise rejects) with a readable message, for example That doesn't look like a valid mobile number., email is required for email handoff or Rate limit exceeded. Please try again later..

Each call is sent with a unique "idempotency key", so a repeated request is only acted on once. Pass your own idempotencyKey (for example crypto.randomUUID() per button press) to make a double click on your button safe.

Picking up an earlier conversation#

Method Returns What it does
resume({ conversation_id, session_token }) a Promise Re-joins an existing conversation. With no argument it reads a <script id="subcontext-resume-payload" type="application/json"> tag on the page. Subcontext's own "carry on chatting" pages use this, and the script calls it itself on load, so you rarely need it.

Before init()#

startChat, ask, contactMe, whatsappMe and toggleVoice fail with a WidgetNotReadyError ("Widget not initialized") if called before init(). The other methods (open, setContext and so on) do nothing.

Events#

The chat sends these events on window. Listen with window.addEventListener(name, handler); the details are in event.detail. Add your listeners before the chat starts so you don't miss any.

Event event.detail When
subcontext:application-ready { id, share_token, customer, risk_factors } The agent has started an insurance application in the chat. A Subcontext quote form on the page uses share_token to follow the same application.
subcontext:voice-state { state: 'idle' or 'active' } Talking in the browser started or stopped, so your own microphone button can show the right state.
subcontext:link { href, path } The visitor clicked a link in the chat that goes to a page on your own website. Call event.preventDefault() to handle it yourself (for example, open your quote form in place). Otherwise the link opens as normal.

Links from Subcontext emails. If the page address has ?ol=... (added to links in emails your firm sends through Subcontext), the chat uses it to recognise the person, removes it from the address bar, and opens a new conversation straight away.

Passing in information about the page or visitor#

Use the subcontext option (or setContext()) to tell the agent what your page already knows. You can pass any JSON object. It is saved with the conversation and shown to your team in the inbox. Only the keys below change what the agent knows or does.

Key What it does
partner For a partner's signed-in pages: { name, customer: { title, first_name, last_name, dob, email, phone, address: { line1, line2, town, postcode } }, insights: [...] }. The agent treats this as unchecked background. It offers the details back for the customer to confirm, instead of asking them to type them, and may mention up to 5 of the insights.
product_slug, journey_slug, presentation_slug The product and quote journey the visitor is looking at (the short names from your quote form setup). With both product_slug and journey_slug (and no page_pin), the agent writes an opening message about that product and the chat starts when opened.
page_pin true means the page is about that journey but the visitor isn't part-way through a quote, so the agent keeps its normal greeting.
opened_from, quote_link Set for you by the openedFrom and quoteLink options.
application_id with application_share_token Links the conversation to a quote form's application. The token is checked, then thrown away (not saved).
current_page, cover_defaults Quote form details: the step the visitor is on and the default cover amounts.
page_url The page that "carry on chatting" links in texts and emails send the visitor back to. If you don't set it, the chat uses the current page address.

Your own reference for the visitor. Put it in subcontext, for example { "your_ref": "CUST-123" }. It is saved with the conversation as you sent it. Subcontext doesn't check it or match it to a contact.

Information is only sent when a new conversation starts. The chat picks up the visitor's saved conversation for up to 24 hours, and that conversation keeps the information it started with. If new information must apply, use freshConversation: true, or call resetConversation() and then setContext().

Campaign tracking#

When a conversation starts, Subcontext reads these from the page address, so you don't need to pass them:

  • utm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_id
  • the ad click ids gclid, gbraid, wbraid, fbclid, msclkid, ttclid and li_fat_id

Other address parameters are ignored. For tracking to work, the visitor must land on an address that has these tags and start the chat on that page.

What else is recorded#

When a conversation starts, the chat also sends:

  • A visitor id: a random id saved in the visitor's browser, so their conversations can be linked together.
  • Where the chat was started: the page address (with personal details removed from it), the referring page, the page title, whether the page is inside a frame (and the outer site, if so), the browser language and the time zone.

Subcontext adds the device and browser type. Together these appear as the conversation's origin details in your inbox, and roll up to the contact. Subcontext also records the visitor's IP address and browser details to deal with abuse; these aren't shown as origin details.

introText, strings and the look-and-feel options are never sent. directDebitPrefill is only sent if the visitor submits the Direct Debit form.

While a visitor types, your team sees a "typing" signal in the inbox (at most once every 1.5 seconds).

Stuck, or something missing?

Get in touch and a person on the team will help.

Contact us