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.jsonto 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-leftbottom-center,top-center,center-right,center-leftcustom— use withpositionOffset(top,right,bottom,leftas CSS lengths, e.g.12px,2rem)
Theme, fonts, and chat bubbles
Beyond primary/background/text, the CDN JSON can include:
theme.fontFamilyandtheme.fontSizefor the widget UItheme.chat.incomingandtheme.chat.outgoing— each supportsfontFamily,fontSize,color, andbubble(background)- Panel chrome:
headerBackground,inputBackground,inputColor,panelWidth,panelHeight,panelRadiusundertheme.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):
| Class | Element |
|---|---|
vt-widget | Root mount |
vt-widget-launcher | Floating pill button |
vt-widget-panel | Open chat panel |
vt-widget-header | Panel header row |
vt-widget-close | Close control |
vt-widget-greeting | Greeting text |
vt-widget-status | Connection / status line |
vt-widget-transcript | Message list |
vt-widget-msg | Message row (base) |
vt-widget-msg--incoming | Incoming message |
vt-widget-msg--outgoing | Outgoing message |
vt-widget-msg--system | System message |
vt-widget-composer | Input row |
vt-widget-input | Text field |
vt-widget-connect | Connect button |
vt-widget-mic-warning | Microphone permission hint |
vt-widget-playback-warning | Autoplay 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.