Each option has a JavaScript name (for init()) and, where there is one, a data-* attribute for the script
tag. Only agentId is required.
A few rules for data-* attributes, because attribute values are always text:
- For on/off options, write exactly
"true". (Fordata-enabled, write"false"to turn it off.) - For lists, write a JSON array, for example
data-conversation-starters='["Hi", "Get a quote"]'.
The basics#
| JavaScript | data-* |
Type | Default | What it does |
|---|---|---|---|---|
agentId |
data-agent-id |
text (an id) | required | Which agent to show. Find it in the dashboard snippet, or in the address bar when you open the agent. |
baseUrl |
data-base-url |
web address | https://subcontext.com |
Where Subcontext lives. You can leave it out. |
mode |
data-mode |
'widget' or 'embedded' |
'widget' |
widget: a launcher button and a pop-up panel. embedded: the chat fills the box named by target, with no launcher, header or close button. |
target |
data-target |
CSS selector, e.g. '#chat' |
none | The box the chat fills in embedded mode (required there). Ignored in widget mode. |
container |
none | CSS selector | none | Another name for target, used by all Subcontext embeds. If you set both, target wins. |
enabled |
data-enabled |
on/off | on | Set to off to load the chat without showing it. Nothing appears or connects until you call enable(). Use it to wait for cookie consent. |
debug |
data-debug |
on/off | off | Writes extra detail to the browser console, starting [Subcontext.Webchat]. Warnings and errors always show, even without it. |
Look and feel#
| JavaScript | data-* |
Type | Default | What it does |
|---|---|---|---|---|
position |
data-position |
'bottom-right' or 'bottom-left' |
'bottom-right' |
Which corner the launcher and panel use. |
primaryColor |
data-primary-color |
any CSS colour | '#2563EB' |
The launcher and the panel header. Hex (3 or 6 digits), rgb(), hsl() or a colour name all work. Soft shadows and focus outlines are mixed from it. |
accentColor |
data-accent-color |
any CSS colour | same as primaryColor |
The send button and the visitor's message bubbles. |
backgroundColor |
data-background-color |
any CSS colour | 'white' (or '#1f1d1a' in dark mode) |
The background of the panel, or of the chat in embedded mode. |
theme |
data-theme |
'light' or 'dark', or (JavaScript only) a theme object |
'light' |
'dark' switches to light text on a dark background. The object form is described below. |
fontFamily |
none | CSS font list | the system font | The chat's font. Your page must already load the font. |
fontSize |
data-font-size |
number (pixels) | 14 |
Size of the messages and the typing box. Any positive number. |
title |
data-title |
text | 'Chat with us' |
The header text until the agent's own name loads (then the agent's name). Screen readers also use it as the name of the launcher and panel. |
variant |
data-variant |
'branded' |
none | A different overall design for the chat. Use 'branded' with the brand option to set your own colours and fonts in it. Other names are designs made for particular Subcontext customers; names Subcontext doesn't know change nothing. |
brand |
none | object | none | The colours and fonts for variant: 'branded': ink, accent, accentSoft, cta, ctaDark, ctaTint (colours) and font, display (font lists). Values that don't look like a colour or a font are ignored. |
launcherIcon |
data-launcher-icon |
text | a chat bubble | Custom launcher icons made for particular Subcontext customers. Leave it out to keep the chat bubble. |
strings |
none | object | English text | Re-word any text the visitor sees. Give only the ones you want to change; see the text you can re-word for the full list. Keep any {tokens}, such as {count}, in the text. |
launchAnimation |
none | function | none | Your own entrance animation for the launcher. See Launcher animation. Widget mode only. |
The theme object (JavaScript only) is the one every Subcontext embed takes, so you can share one theme between the webchat, quote form, form guide, lead form and Nurture. Theming the embeds says what each embed does with each key.
theme: {
primaryColor: '#0F3D3E',
accentColor: '#E07A5F',
backgroundColor: '#FFFDF8',
fontFamily: "'Georgia', serif",
fontSize: 15,
mode: 'light' // or 'dark'
}
Values in the theme object win over the separate options with the same name. Unknown keys are ignored.
theme: 'dark' and theme: { mode: 'dark' } mean the same.
How it behaves#
| JavaScript | data-* |
Type | Default | What it does |
|---|---|---|---|---|
defaultOpen |
data-default-open |
on/off | off | Opens the panel once the agent loads, on larger screens only. It doesn't move the visitor's keyboard focus. It is skipped on phones, when launchAnimation or startUnread is set, and if the visitor closed the panel earlier in this browser tab. |
defaultExpanded |
data-default-expanded |
on/off | off | Opens the panel in its large size (760 by 1040 pixels). open({ expanded }) overrides it. |
startUnread |
data-start-unread |
on/off | off | Shows a red dot on the launcher until the visitor first opens it. Not shown again once they have closed the chat in this tab. |
conversationStarters |
data-conversation-starters |
list of text | none | Up to 6 suggested questions under the greeting in a new conversation. Clicking one sends it as the visitor's first message. |
starterMessage |
data-starter-message |
text | none | Sent as the visitor's first message when the conversation starts. In embedded mode, that is as soon as the agent loads. In widget mode, it is when a conversation starts (for example from startChat()); if the visitor types first, it is sent just before their message. In widget mode, ask() is usually the better choice. |
introText |
none | text | the agent's own greeting | Replaces the agent's greeting on this page. It is only shown in the browser. Nothing is sent or saved. Leave a blank line to split it into separate bubbles. Markdown (simple formatting like **bold**) works. |
animateOpener |
data-animate-opener |
on/off | off | Shows the greeting bubbles one at a time, with a typing indicator between them. |
freshConversation |
data-fresh-conversation |
on/off | off | Starts a new conversation instead of picking up the one saved in this browser, and forgets that the visitor closed the panel. |
omni |
data-omni |
list of 'whatsapp', 'sms', 'email', 'phone', 'mic' |
none | Replaces the header's microphone button with a Switch channel button that lists these choices, in this order. phone asks for a call back; mic is talking in the browser. Unknown values are ignored. |
openedFrom |
data-opened-from |
'website' or 'quote_form' |
none | Where the chat was opened from. 'quote_form' uses the greeting and suggested questions the agent has for quote forms; 'website' uses its normal greeting and your conversationStarters. |
quoteLink |
none | { href, label } (label optional) |
none | A link to your quote form. In a 'website' chat, when the visitor wants a quote, the agent sends them to this link instead of asking the quote questions in the chat. |
rememberClickIds |
data-remember-click-ids |
true/false |
Google Consent Mode | Whether ad click ids from the page a visitor lands on may be kept in your website's browser storage, so a chat or form on a later page still sends them. Unset: follows Consent Mode's ad_storage, else nothing is kept. See Ad clicks across pages. |
directDebitPrefill |
none | object | none | Fills in the Direct Debit form if the agent shows one: accountHolderName, sortCode, accountNumber, addressLine1, addressLine2, city, postcode. It stays in the browser until the visitor submits the form. |
Information about the page or visitor#
| JavaScript | data-* |
Type | Default | What it does |
|---|---|---|---|---|
subcontext |
data-subcontext |
object (a JSON string in data-*; invalid JSON is ignored) |
none | Facts about the page or visitor. Saved with the conversation when it starts. See Passing in information. |
Launcher animation#
The chat has no entrance animation of its own. To add one, pass a function. It receives the launcher
button and three helpers. While your function runs, the button has the class sc-fly, which turns
off its own transition so it doesn't interfere with your animation.
SubcontextWebchat.init({
agentId: 'YOUR_AGENT_ID',
baseUrl: 'https://subcontext.com',
launchAnimation(fab, hooks) {
// hooks.isFullScreen(): true on a phone, where the panel would fill the screen
// hooks.isStale(): true if the chat has redrawn the launcher (stop animating)
// hooks.onLand(): call it to open the small panel
fab.animate([{ transform: 'translateY(120px)' }, { transform: 'none' }], { duration: 600, easing: 'ease-out' })
}
})
Once the visitor has closed the panel in a browser tab, the animation doesn't play again on later pages in that tab.
Text you can re-word#
Pass any of these in strings to change the text. Keep any text in {curly brackets}: the chat fills it in.
| Key | Default text |
|---|---|
| Typing box and connection | |
inputPlaceholder |
Type a message... |
sendMessage |
Send message |
reconnecting |
Reconnecting… |
connectingToAgent |
Connecting you to our AI agent… |
couldNotConnect |
Could not connect. Please try again. |
| Header buttons (also read out by screen readers) | |
unreadMessages |
{count} unread |
closeChat |
Close chat |
expandChat |
Expand chat |
collapseChat |
Collapse chat |
startVoice |
Start voice conversation |
stopVoice |
Stop voice conversation |
talkToAgent |
Talk to the agent |
Switch channel (the omni option) |
|
omniSwitchChannel |
Switch channel |
omniWhatsapp |
|
omniSms |
Text message |
omniEmail |
|
omniPhone |
Call me |
omniMic |
Voice chat |
omniAskPhone |
Enter your phone number and we'll continue there. |
omniAskEmail |
Enter your email and we'll continue there. |
omniPhonePlaceholder |
Phone number |
omniEmailPlaceholder |
Email address |
omniSubmit |
Continue |
omniCancel |
Cancel |
omniSending |
Sending… |
omniConsent |
By continuing you agree to be contacted about your enquiry. |
omniReconfirm |
You asked us before to stop messaging you there. Continue only if you'd like us to start again. |
omniReconfirmSubmit |
Yes, message me there |
omniInvalidPhone |
Please enter a valid phone number. |
omniInvalidEmail |
Please enter a valid email address. |
omniError |
Sorry, that didn't work. Please try again. |
omniSuccess |
Thanks: we'll continue there shortly. |
omniSuccessSms |
We can't reach you on WhatsApp right now, so we've sent you a text instead. |
omniUnavailable |
Sorry, we can't continue on WhatsApp right now. Please carry on here. |
omniUnavailableOther |
Sorry, we can't continue on that channel right now. Please carry on here. |
| Talking in the browser | |
voiceConnecting |
Connecting… |
voiceListening |
Listening: say something |
voiceStopping |
Stopping… |
voiceAllowMic |
Allow microphone access… |
voiceUnavailable |
Voice unavailable |
voiceAgentNotReady |
Agent not ready: try again in a moment. |
voiceCouldNotStartConversation |
Could not start the conversation. |
voiceLimitReached |
Voice limit reached for today. |
voiceMicBlocked |
Microphone access was blocked. Allow it in your browser settings (look for the mic icon in the address bar) and tap the mic again. |
voiceNoMic |
We couldn't find a microphone on this device. |
voiceMicBusy |
Your microphone is being used by another app. Close it and try again. |
voiceNeedsHttps |
Voice needs a secure (https) connection. Reload the site over https and try again. |
voiceCouldNotStart |
Voice could not start. Please try again. |
| General messages (used when Subcontext doesn't send its own wording) | |
messageBlocked |
Message blocked. |
conversationClosed |
This conversation has been closed. |
slowDown |
Please slow down. |
somethingWentWrong |
Something went wrong. |
| Payments | |
paymentReceived |
Payment received. Confirming with the insurer… |
paymentFormTitle |
Payment |
directDebitMandateTitle |
Direct Debit |
| Direct Debit form | |
ddTitle |
Set up your monthly payments |
ddBlurb |
We'll use these UK bank details to collect each monthly premium by Direct Debit. |
ddTestTitle |
Test mode: use these Direct Debit details. |
ddAccountHolder |
Account holder name |
ddSortCode |
Sort code |
ddAccountNumber |
Account number |
ddAddressLine1 |
Billing address |
ddAddressLine2 |
Address line 2 (optional) |
ddAddressCity |
City |
ddAddressPostcode |
Postcode |
ddAddressRequired |
Please enter your billing address, city and postcode. |
ddSubmit |
Submit |
ddSubmitting |
Submitting… |
ddSubmitted |
Submitted |
ddNetworkError |
Network error |
ddCaptured |
Direct Debit set up |
ddCapturedFallback |
Your bank details have been received. |
| Policy confirmation | |
policyHeading |
Policy {number} is on cover |
policyHeadingNoNumber |
Your policy is on cover |
policyEffectiveFrom |
Effective from {date}. |
policyDocsTitle |
Your documents |
policySchedule |
Your policy schedule |
policyDocFallback |
document |
policyManage |
Manage your policy |
| Comparing quotes | |
marketSearching |
Searching the whole market for you… |
marketSearchingScope |
Searching {scope} for you… |
marketHeading |
Your quotes: {count} options, cheapest first |
marketPerMonth |
per month |
marketCheapest |
Cheapest |
marketSelected |
Selected |
marketVaried |
Adjusted by provider |
marketEvidence |
Medical evidence needed |
marketChooseHint |
Pick an option below, or just tell us which one you’d like. |
marketSelect |
Select |
marketSelectBusy |
Saving… |
marketSelectFailed |
That didn’t save: please try again, or just tell us which one you’d like. |
handoffHeading |
Finish your application with {provider} |
handoffHeadingNoProvider |
Finish your application with your chosen provider |
handoffPremiumNote |
Your quote: {premium}/month |
handoffContinue |
Continue with {provider} → |
handoffContinueNoProvider |
Continue to your provider → |