Skip to main content

How Theming Works

The widget ships with two built-in palettes, light and dark. A theme is simply a set of overrides layered on top of one of them:
Everything you don’t specify keeps the value from the base palette, so a theme can be two lines or fifty. You never need to restyle the whole widget just to change one color.
A theme becomes a set of CSS custom properties set on the widget’s host element, which the widget’s shadow DOM reads from the inside. Because the markup lives in a shadow root, your page’s stylesheets can’t select into the widget, and the widget’s own styles can’t leak out onto your page.

Step 1: Build the Theme

The fastest way to produce a theme is the SDK Playground - it gives you every control as a form field with a live widget next to it, so you can see each change immediately. Enter your campaign ID and secret, then click Load SDK.
Playground configuration panel with campaign ID, secret, variables, and FAB text

Loading a campaign in the playground

Now scroll to Theme Customization and start adjusting. Press Apply Theme to push your changes into the live widget, or Reset to go back to the base palette.
Theme customization panel with General, Launcher, Background, Questions, and Answers groups

The theme builder - every control maps to one field in the theme configuration

The configuration on the right rebuilds itself as you touch the controls, so you are always looking at the exact JSON your current settings produce. The widget in the corner only restyles when you press Apply Theme - that’s the moment your configuration is handed to the running widget.
Playground with a loaded campaign, the base palette set to Dark, the generated theme configuration, and the live widget button

Switching the base to Dark: the live widget and the generated configuration update together

What Each Group Controls

The starting palette (light or dark), the font family, and the floating action button - its background color and icon color.
Everything the visitor sees before the conversation starts: the collapsed launcher pill and its label, the call-to-action button on the pre-call card, the frosted close button, the connecting indicator, and the divider shown after a call finishes.
Surface colors for the three regions of the panel - the header, the chat area, and the bottom bar - plus their borders.
How the agent’s side of the conversation looks: title color, size, and alignment, the secondary text color, and the agent’s message bubble.
How the visitor’s side looks: text inputs (filled or outlined, corner radius), the submit button, choice selectors, and the visitor’s own message bubble.
The hang-up button keeps a fixed red color in every theme. It is deliberately not overridable - visitors need to recognize it instantly.

Step 2: Apply the Theme

When the widget looks right, copy the generated configuration from the playground.
Generated setTheme call containing a full widget theme configuration

The generated theme configuration, ready to copy

There are three places you can put it. Pick the one that matches how you installed the widget.

On the Script Tag

If you installed the widget with the embed snippet, add a data-theme attribute. It takes the full configuration as JSON:
For a plain light or dark widget with no other changes, there’s a shorthand:
The attribute value must be valid JSON in single quotes. If it can’t be parsed, the SDK logs an error to the browser console and falls back to the default theme.

In the SDK

If you build your own integration, pass the configuration as the theme option:
The SDK also exports the two built-in palettes, so you can start from one and override just what you need:

At Runtime

Call setTheme() to restyle a widget that’s already on the page. This is what you want if your site has its own light/dark switch:
The change applies immediately, including mid-conversation.

Which Theme Wins

A widget can receive a theme from two directions, so the order matters:
1

A theme you pass explicitly

Anything set through data-theme, the theme option, or setTheme() always wins.
2

The campaign's configured theme

If you pass nothing, the widget uses the theme saved on the campaign, fetched when it loads.
3

The default light palette

If neither exists, the widget falls back to Default Light.
In practice: set the theme on the campaign so every installation looks right by default, and override it in code only where a specific site needs something different.

Configuration Reference

Every field is optional except base. Anything you leave out inherits from the base palette.

Top Level

Floating Button - fab

Panel Surfaces - sections

Agent Side - questions

Visitor Side - answers

Scale Values

The size and radius keywords resolve to fixed values, so spacing stays consistent no matter which you pick: Colors accept any CSS color value - hex, rgb(), or rgba() when you need transparency.

A Complete Example

A dark widget in a deep blue brand palette:

Next Steps