message.comDevelopers

Customization Live

Most teams customise the widget entirely from the dashboard, no code required. For advanced cases (per-page overrides, fully custom launchers, dynamic themes) you can override via data attributes or runtime API calls.

The widget renders inside Shadow DOM, so your site CSS cannot reach in. That is a feature: it prevents accidental style breakage across thousands of customer sites. Customisation flows through the explicit knobs documented here, not arbitrary CSS injection.

Dashboard settings

The fastest way to customise the widget is in the dashboard at /settings/chats/customization. Every setting persists to the workspace (or to a specific site, if you use multi-site mode) and propagates to live embeds within 60 seconds.

Dashboard fields
Workspace → Settings → Chats → Customization

• Primary color
• Launcher position (right / left)
• Launcher icon (default / minimal / custom SVG)
• Bottom spacing (px)
• Welcome heading
• Welcome message
• Pre-chat form fields
• Office-hours availability copy
• Brand logo (panel header)
• Avatar fallback color

For full design-system control across multiple brands, you can run multiple sites in one workspace. Each site holds its own theme. See Sites API.

Advanced data attributes

For per-page overrides, set data attributes on the script tag. They override the dashboard defaults for that page load only.

HTML
<script src="https://app.message.com/widget.js"
  data-workspace="abc123"
  data-position="right"
  data-bottom-spacing="20"
  data-side-spacing="20"
  data-color="#FF4D1F"
  data-launcher-shape="rounded"
  data-launcher-icon="default"
  data-no-launcher="false"
  data-greeting="Hi! Need a hand?"
  data-locale="en"
></script>

For the full attribute list see Widget configuration.

Runtime theme override

If you need to flip the theme at runtime (for example, switch to a high-contrast skin when the user toggles a dark-mode preference), call Message.setTheme.

JavaScript
// Push a per-page theme override.
Message.setTheme({
  primaryColor: '#0066FF',
  position: 'left',
  bottomSpacing: 80  // get out of the way of a sticky footer
});

The override is session-local. It does not change the dashboard default. Reload the page and the workspace default applies again.

Custom launcher

To replace the launcher button entirely with your own UI, set data-no-launcher="true" and wire your button to Message.toggle(). The chat panel still mounts inside Shadow DOM, so you only need to draw the entry point.

HTML · custom launcher
<script src="https://app.message.com/widget.js"
  data-workspace="abc123"
  data-no-launcher="true"
></script>

<button class="my-chat-button" onclick="Message.toggle()">
  Chat with us
  <span class="unread" id="unread-count"></span>
</button>

<script>
  Message.on('ready', () => {
    Message.on('message:received', () => {
      document.getElementById('unread-count').textContent = '1';
    });
    Message.on('open', () => {
      document.getElementById('unread-count').textContent = '';
    });
  });
</script>

If you want to replace the chat panel itself, not just the launcher, you need a deeper integration. See the planned React components SDK for an unstyled-primitives surface (Planned).

Localisation

The widget ships with built-in copy in English, Spanish, French, German, Portuguese, Italian, Dutch, Japanese, and Chinese. Pass data-locale or set the workspace default in the dashboard. Unsupported locales silently fall back to English.

To override individual strings (for example, change “Send a message” to brand-specific copy), use the per-string overrides in /settings/chats/language. See Multilingual customers.

Accessibility

The widget targets WCAG 2.1 AA. Launcher buttons have aria-labels, the chat panel is keyboard navigable, message timestamps are screen-reader friendly, and focus is managed when the panel opens or closes. Colour choices in the dashboard surface a contrast warning if the picked primary fails contrast against white.

If your brand colour fails contrast, the widget auto-derives a darker shade for text and icons inside the launcher. The override is purely cosmetic and does not affect agent-side rendering.

Common pitfalls

  • Trying to style inside the Shadow DOM with site CSS. Selectors cannot pierce the Shadow root. Use the documented knobs or the React components SDK when it ships.
  • Inconsistent themes across pages. If different pages set conflicting data-color values, visitors see the launcher flicker on each navigation. Pick one source of truth: dashboard or data attributes, not both.
  • Sticky footers covering the launcher. Sites with sticky bottom bars often need a higher data-bottom-spacing value. The default 20px assumes a clear viewport bottom.
  • Custom locales without translations. The data-locale attribute only swaps language for built-in copy. Custom welcome messages are not auto-translated. Set them per locale via the dashboard.