Reference
Web chat widget
Embed a Cradle-backed chat widget on any website with a single script tag — history, typing indicator, and real-time replies.
The Cradle web widget is a full chat channel, not a contact form. A visitor sees a floating button, opens a chat window with message history, sends a message, and receives a reply from Cradle in real time.
Bundle size: ~49 KB gzipped.
Embed
Add one script tag to any page:
<script
src="https://cradle.example.com:31415/widget.js"
data-cradle-widget
data-api-key="wk_..."
data-accent="#10b981"
data-position="bottom-right"
async></script>Replace the host and port with wherever your Cradle widget endpoint is reachable.
For local testing this is http://localhost:31415/widget.js.
Configuration attributes
| Attribute | Required | Description |
|---|---|---|
src | yes | Widget bundle URL |
data-cradle-widget | yes | Mount marker |
data-api-key | yes | Widget API key from channel config |
data-accent | no | Hex color for the launcher and send button |
data-position | no | bottom-right (default) or bottom-left |
Server-side theme, position, and locale are returned by
GET /api/widget/config/:apiKey. Client attributes override some values.
Architecture
packages/widget/— Vite IIFE bundle, React inlined.src/core/channels/widget-channel.ts— Fastify server in the main process.- Shadow DOM mount isolates styles from the host page.
- No
postMessageto the parent window: all communication goes through HTTP and WebSocket to Cradle.
Server endpoints
| Endpoint | Purpose |
|---|---|
GET /widget.js | Serve the bundle with long cache headers |
GET /api/widget/config/:apiKey | Theme, color, position, locale |
POST /api/widget/message | Accept a visitor message (X-Visitor-Id header) |
WS /api/widget/ws?visitorId=...&apiKey=... | Real-time replies and typing events |
Client behavior
visitorIdis generated on first open and stored inlocalStorage.- Chat history is cached locally, so a page reload keeps the conversation.
- WebSocket auto-reconnects with exponential backoff.
- Typing indicator shows while a reply is pending.
Security
- Widget API key is configured per channel in
channels_config.widget.config.apiKey. - Optional
allowedOriginslist restricts which sites can load the widget. - Rate limit is applied per IP + key.
- For production, expose the widget endpoint through a reverse proxy or tunnel and serve it over HTTPS.