Embed widget designer

The Widget tab on each project lets you style the floating chat launcher visitors see on your site — presets, brand colors, corner or custom position, chat fonts and bubbles, optional custom CSS, launcher label, and greeting. Preview updates live in the dashboard; Deploy publishes appearance settings to the VoiceThere CDN so customer pages can load theme changes without redeploying their own HTML.

Dashboard: Widget tab

  • Path: Project → Widget (/projects/:projectId/widget)
  • Presets: pill-dark, pill-light, rounded-card, minimal-bar, voice-orb
  • Brand colors: primary, background, and text (hex)
  • Save draft: stores styling in the project database — preview reflects the draft immediately
  • Deploy: publishes a public config.json to the VoiceThere CDN and purges the stable URL so browsers fetch the latest revision

Live preview chat

The designer preview can open the panel and tap Connectto start a real session using your project's client key (same credits and behavior as the dashboard Chat tab). The project must be deployed with a live agent build before Connect succeeds.

Launcher and position

When the chat panel is open, the floating launcher pill is hidden so it does not overlap the panel. Closing the panel restores the pill.

Published config supports eight named corners/edges plus custom:

  • bottom-right, bottom-left, top-right, top-left
  • bottom-center, top-center, center-right, center-left
  • custom — use with positionOffset (top, right, bottom, left as CSS lengths, e.g. 12px, 2rem)

Theme, fonts, and chat bubbles

Beyond primary/background/text, the CDN JSON can include:

  • theme.fontFamily and theme.fontSize for the widget UI
  • theme.chat.incoming and theme.chat.outgoing — each supports fontFamily, fontSize, color, and bubble (background)
  • Panel chrome: headerBackground, inputBackground, inputColor, panelWidth, panelHeight, panelRadius under theme.chat

Requires @voicethere/client 0.8.2+ to apply these fields on the live embed. Older clients still mount but ignore unknown CDN keys (fail-soft parse).

Custom CSS and class hooks

Optional customCss in the published JSON (max 16 KiB; must not contain </style). The client injects rules via a style element's textContent, scoped under .vt-widget. The dashboard designer keeps custom CSS collapsed until you expand it.

Stable BEM-style classes (scope selectors under .vt-widget):

ClassElement
vt-widgetRoot mount
vt-widget-launcherFloating pill button
vt-widget-panelOpen chat panel
vt-widget-headerPanel header row
vt-widget-closeClose control
vt-widget-greetingGreeting text
vt-widget-statusConnection / status line
vt-widget-transcriptMessage list
vt-widget-msgMessage row (base)
vt-widget-msg--incomingIncoming message
vt-widget-msg--outgoingOutgoing message
vt-widget-msg--systemSystem message
vt-widget-composerInput row
vt-widget-inputText field
vt-widget-connectConnect button
vt-widget-mic-warningMicrophone permission hint
vt-widget-playback-warningAutoplay hint

CSS variables set from theme (on the widget root):

  • --vt-color-primary
  • --vt-color-bg
  • --vt-color-text
  • --vt-font-ui
  • --vt-font-size-ui
  • --vt-font-incoming
  • --vt-font-outgoing
  • --vt-font-size-incoming
  • --vt-font-size-outgoing
  • --vt-bubble-incoming-bg
  • --vt-bubble-incoming-fg
  • --vt-bubble-outgoing-bg
  • --vt-bubble-outgoing-fg
  • --vt-header-bg
  • --vt-input-bg
  • --vt-input-fg
  • --vt-panel-width
  • --vt-panel-height
  • --vt-panel-radius

Example custom CSS targeting incoming bubbles:

.vt-widget .vt-widget-msg--incoming {
  font-weight: 600;
  border-radius: 1rem 1rem 1rem 0.25rem;
}

Public config (no client API key)

The published JSON contains appearance and bootstrap fields only— preset, theme, position, positionOffset, customCss, labels, projectId, apiBase, mode, and revision. It never includes your clientKey or other secrets.

After Deploy succeeds, the Widget tab and Access page show the stable CDN URL:

https://cdn.voicethere.io/widgets/w_…/config.json

The opaque w_… segment is a public widget id — not your project UUID. Appearance is served from a dedicated VoiceThere CDN hostname (production cdn.voicethere.io).

Embed on your site

Paste the embed snippet from Project → Access (@voicethere/client 0.8.2). Keep your clientKey, projectId, and apiBase in the host page — the CDN JSON never includes the key.

<script type="module">
  import { createVoiceThereWidgetAsync } from "https://esm.sh/@voicethere/client@0.8.2/embed";

  await createVoiceThereWidgetAsync({
    apiBase: "https://sessions.voicethere.io/v1",
    projectId: "your-project-uuid",
    clientKey: "vtc_…",
    mode: "chat",
    configUrl: "https://cdn.voicethere.io/widgets/w_…/config.json",
  });
</script>

configUrl is included only after you Deploy the widget. If the CDN JSON is missing or unreachable, the client still mounts from your inline options and logs a console warning — useful before the first Deploy or during a brief CDN propagation window.

For iframe permissions, microphone fallback, and autoplay behavior, see Browser client → Embed widget.

CORS for your site

The CDN JSON is a public GET (no credentials). Your production and staging site origins still belong on Project → Access → Allowed web origins so the browser can call the sessions API with your client key.

Browser CORS origins

← All documentation