Web quickstart
Embed Kustomer Chat on a website with widget.js, start it with Kustomer.start, control it from your code, and listen for widget events. Includes every start option and widget method.
The web SDK ships as a script you load from Kustomer's CDN. It comes in two builds:
This page covers the widget.
Embed the widget
Get a chat key
In Kustomer, go to Settings › Security › API Keys and create a key with only the
org.trackingrole. Chat keys are safe to put in a web page because that role can do nothing but chat as an anonymous or logged-in customer. See API keys and roles.Add the script
Put this before
</body>on every page that should have chat:index.html<script src="https://cdn.kustomerapp.com/chat-web/widget.js" data-kustomer-api-key="YOUR_CHAT_KEY" ></script> <script> window.addEventListener('kustomerLoaded', function () { Kustomer.start({ brandId: 'YOUR_BRAND_ID' }) }) </script>The loader reads the key from
data-kustomer-api-key, defineswindow.Kustomerwith onlystart, requests the rest of the SDK, and fireskustomerLoadedonwindowstraight away. Thestartcall is queued until the SDK arrives. Call every other method from thestartcallback or later.Pick a brand
brandIdchooses which chat settings to use: colors, greeting, business hours and assistant. List your brands and their IDs withGET /v1/brands. Leave it out to use the default brand.Test it
Load the page, open chat and send a message. It appears in Kustomer as a new chat conversation on an anonymous customer. Reply from Kustomer and watch it arrive in the widget. To try your key and brand before touching your site, use the playground below.
Single-page apps
Load the script once for the lifetime of the app, not on every route change, and keep Kustomer.start out of render paths:
import { useEffect } from 'react'
declare global {
interface Window { Kustomer?: any }
}
export function ChatProvider({ brandId }: { brandId: string }) {
useEffect(() => {
if (document.querySelector('[data-kustomer-api-key]')) return
const onLoaded = () => window.Kustomer.start({ brandId })
window.addEventListener('kustomerLoaded', onLoaded, { once: true })
const script = document.createElement('script')
script.src = 'https://cdn.kustomerapp.com/chat-web/widget.js'
script.dataset.kustomerApiKey = import.meta.env.VITE_KUSTOMER_CHAT_KEY
document.body.appendChild(script)
}, [brandId])
return null
}To tear chat down, for example when a user switches accounts, call Kustomer.stop(). It removes the widget iframe, and a later Kustomer.start() builds it again.
Shopify
On Shopify storefronts the loader picks up window.Shopify.shop automatically. Elsewhere, pass the store domain with data-kustomer-shop="acme.myshopify.com" on the script tag.
Kustomer knowledge base
To show chat on a knowledge base hosted by Kustomer, add the loader to a custom theme. The default theme doesn't accept new files, so duplicate it first.
Add a global script
In Kustomer, open Settings › Knowledge Base › Themes, choose your custom theme, and in Theme Files select Add. Create a file with Theme Target
Global, File Namechatand File TypeJS.Load the widget from it
Paste the loader into
chat.js, save, and apply the theme:chat.jswindow.addEventListener('DOMContentLoaded', function () { var script = document.createElement('script') script.src = 'https://cdn.kustomerapp.com/chat-web/widget.js' script.setAttribute('data-kustomer-api-key', 'YOUR_CHAT_KEY') document.body.appendChild(script) }) window.addEventListener('kustomerLoaded', function () { Kustomer.start({ brandId: 'YOUR_BRAND_ID' }) })
Use the brand that owns the knowledge base, so chat and articles share the same branding.
Playground
Run the real widget here with your own chat key. It loads into an example storefront, so you can check the key, brand, assistant and start options, call any widget method, and watch the events your code would receive. The Embed code tab gives you the snippet for the options you picked.
›Start options
Paste a chat key and launch
Create one in Kustomer under Settings › Security › API Keys with only the org.tracking role. The real widget then loads into an example storefront here.
The playground refuses keys with any role besides org.tracking, since only chat keys are safe in a web page. If your brand uses page rules, add one that matches this site, or the launcher stays hidden here. See Customization and security.
Start options
Kustomer.start(options, callback) builds the widget. The callback runs once it's ready, and methods that need a started widget, such as getOpenConversations, must run after it.
Kustomer.start(
{
brandId: 'YOUR_BRAND_ID',
assistantId: 'YOUR_ASSISTANT_ID',
scheduleId: 'YOUR_SCHEDULE_ID',
lang: 'fr',
preferredView: 'chat',
chatIconPosition: { alignment: 'left', horizontalPadding: 24, verticalPadding: 24 },
chatIconSize: 56,
zIndex: 1000,
hideChatIcon: false,
hideHistory: false,
showBrowserNotifications: true,
showTitleNotifications: true,
},
function () {
console.log('Chat is ready')
},
)brandIdstring- The brand whose chat settings to use. Defaults to the org's default brand.
assistantIdstring- Start new conversations with this assistant (chatbot) instead of the brand's default.
scheduleIdstring- Use this business schedule for availability instead of the brand's.
langstring- UI language, such as
en_us,es,fr,pt_brorzh_cn. Defaults to the browser's language.pt-BRstyle codes work too, and unknown regions fall back to the base language. Arabic and Hebrew render right to left. preferredView'chat' | 'kb'- Which screen opens first when the brand has both chat and a knowledge base.
Kustomer.constants.CHAT_HISTORY_VIEWandKustomer.constants.KNOWLEDGE_BASE_VIEWhold the two values. chatIconPosition'right' | 'left' | object- Which corner the launcher sits in. Pass an object to set the padding too:
{ alignment: 'right', horizontalPadding: 20, verticalPadding: 20 }(the default, in pixels). chatIconSizenumber | string | object- Launcher size in pixels:
56,'56px', or{ width: 56, height: 56 }. zIndexnumber- Stacking order of the widget iframe. Defaults to
2147483000, the top of almost every page. hideChatIconboolean- Hide the launcher. Open chat from your own button with
Kustomer.open(). hideHistoryboolean- Hide the list of past conversations.
hideNewConversationButtonOnHistoryboolean- Hide New conversation on the history screen.
hideNewConversationButtonOnEndboolean- Hide New conversation when a conversation ends.
hideArticleOpenInNewTabboolean- Hide the button that opens a knowledge base article in a new tab.
showBrowserNotificationsboolean- Show desktop notifications for new messages while the tab is in the background, after the visitor grants permission.
showTitleNotificationsboolean- Flash the tab title when a message arrives in a background tab.
allowZoomboolean- Allow pinch zoom inside the widget on mobile browsers.
enableUrlUnfurlingboolean- Show link previews for URLs in messages.
enableHistoryStatusFilterboolean- Show a status filter on the history screen. Set the initial value with
historyStatusFilter('all','open'or'closed'), or change it later withKustomer.setHistoryStatusFilter('open').
Most of the widget's look is configured in Kustomer, not in code: colors, greeting, team name and icon, business hours, offline behavior and which sites may embed it. See Customization and security.
Control the widget
Call these from the start callback or later. Before the SDK finishes loading they don't exist yet, and before start builds the widget most of them silently do nothing. Callbacks follow the (response, error) convention.
Start a conversation from your page
Open chat with a new conversation, for example from a Help with this order button:
document.querySelector('#order-help').addEventListener('click', function () {
Kustomer.createConversation(
{
message: 'I need help with order #4417',
customAttributes: { orderNumberStr: '4417' },
},
function (conversation, error) {
if (error) return console.error(error)
console.log('Created', conversation.conversationId)
},
)
})messagestring- The first message, sent as the customer.
customAttributesobject- Custom attributes for the new conversation, using the conversation Klass's attribute names. See Custom attributes.
assistantIdstring- Start this conversation with a specific assistant.
dialogIdstring- Start the assistant at a specific dialog.
payloadstring- A payload passed to the assistant with the first message.
The callback receives the conversation: conversationId, createdAt, ended and, when it starts with an assistant, isInAssistantMode.
Events
function onUnread({ total, change }) {
document.querySelector('#chat-badge').textContent = total || ''
console.log(`${change.count} unread in ${change.conversationId}`)
}
Kustomer.addListener('onUnread', onUnread)
// later
Kustomer.removeListener('onUnread', onUnread)Unknown event names are rejected with a console error. The Core API has a longer event list, including every message received; see Web Core API › Events.