Skip to Content
🎉 Welcome to Delivery Chat Documentation
V1Chat Widget Integration

Chat Widget Integration

The Delivery Chat widget is a vanilla JavaScript embed that adds a chat launcher and chat window to any website. No framework required—works with React, Vue, plain HTML, or any stack.

⚠️

Prerequisite: Application ID

You need an appId to use the widget. Create an application in your dashboard first.

AI Quickstart

Copy this prompt into your AI coding assistant (Cursor, Copilot, Claude, etc.) to get a working integration in one shot:

Widget Embed PromptAI

Quick Start

Add this snippet before </body> (or in <head>). The queue-stub pattern ensures calls are safe to make immediately — no race conditions:

<script> (function(w,d,s,o){ w.DeliveryChat=w.DeliveryChat||function(){(w.DeliveryChat.queue=w.DeliveryChat.queue||[]).push(arguments)}; var js=d.createElement(s);js.async=1;js.src='https://api.deliverychat.online/widget.js'; d.head.appendChild(js); })(window,document,'script'); DeliveryChat('init', { appId: 'YOUR_APP_ID' }); </script>

Replace YOUR_APP_ID with your application UUID from the dashboard.

How the queue-stub works

The snippet creates a lightweight DeliveryChat function that queues all calls. When the real script loads, it replays the queue in order. This means:

  • You can call DeliveryChat('init', ...) immediately — no race condition.
  • Event listeners registered via DeliveryChat('on', ...) before load are preserved.
  • The script loads asynchronously and never blocks page rendering.

Init Options

OptionTypeRequiredDescription
appIdstringYesYour application UUID from the dashboard
apiBaseUrlstringNoOverride the API URL. Auto-detected from the script src by default
position"bottom-left" | "bottom-right"NoLauncher position. Default: "bottom-right"
autoOpenbooleanNoOpen chat automatically on load. Default: false
autoOpenDelaynumberNoDelay in ms before auto-open. Default: 5000
colorsobjectNoOverride specific colors (e.g. { primary: "#6366f1" })
ℹ️

apiBaseUrl is optional for CDN

When using the CDN embed, apiBaseUrl is auto-detected from the script src attribute. Only pass it if you self-host the widget bundle on a different domain than the API. If provided, it must be origin-only — never append /api/v1.

Example with all options

DeliveryChat('init', { appId: 'app_abc123', position: 'bottom-left', autoOpen: true, autoOpenDelay: 3000, colors: { primary: '#6366f1', background: '#ffffff', text: '#0f172a', }, });

Controlling the Widget

After the script loads, DeliveryChat becomes an object with direct methods:

DeliveryChat.open(); // Open the chat window DeliveryChat.close(); // Close it DeliveryChat.toggle(); // Toggle open/close DeliveryChat.hideWidget(); // Hide the launcher button DeliveryChat.showWidget(); // Show it again DeliveryChat.sendMessage('Hello!'); DeliveryChat.destroy(); // Remove widget and clean up

Queue commands (before script loads)

Before the script finishes loading, use the function-call syntax:

DeliveryChat('init', { appId: 'YOUR_APP_ID' }); DeliveryChat('on', 'ready', function() { console.log('Widget ready'); }); DeliveryChat('sendMessage', 'Hello!'); DeliveryChat('identify', { name: 'Jane', email: 'jane@example.com' });

Events

DeliveryChat.on('message:received', function(message) { console.log('New message:', message.content); }); DeliveryChat.on('unread:changed', function(data) { document.title = data.count > 0 ? '(' + data.count + ') My App' : 'My App'; });

Available events: ready, open, close, message:received, message:sent, conversation:started, conversation:resolved, unread:changed.

Destroying the Widget

To remove the widget (e.g. on SPA route change or logout):

DeliveryChat.destroy();

This cleans up event listeners, removes the DOM, and resets state. You can call DeliveryChat.init() again afterward to re-initialize.

Settings from the API

The widget fetches configuration from the API on initialization:

GET {apiBaseUrl}/api/v1/widget/settings/:appId

This endpoint is public (no auth). It returns JSON:

{ "settings": { "colors": { "primary": "#0ea5e9", "background": "#ffffff" }, "font": { "family": "system-ui", "size": "14px" }, "position": { "corner": "bottom-right", "offset": "16px" }, "header": { "title": "Chat with us", "subtitle": "...", "showLogo": true, "logoUrl": "..." }, "launcher": { "icon": "chat", "label": "Open chat" }, "behavior": { "autoOpen": false, "autoOpenDelay": 5000 } } }

Settings are stored in applications.settings (JSONB) and managed from your dashboard. Init options override API settings—e.g. position: "bottom-left" in init() overrides the API position.corner.

Customization

Dashboard settings

Configure colors, fonts, header, launcher, and behavior in your application settings. These are fetched automatically when the widget loads.

Init overrides

Override any setting at init time. Useful for A/B tests or per-page behavior:

DeliveryChat('init', { appId: 'app_abc123', position: 'bottom-left', autoOpen: true, colors: { primary: '#ff0000' }, });

Launcher icons

The launcher supports three icon types: "chat", "question", and "message". Set via applications.settings.launcher.icon.

Security

The widget authenticates using domain-based origin validation. When you create an application, you register a domain (e.g. nike.com). The server validates that widget requests originate from that domain — no API key is exposed in client-side code.

  • Requests from matching domains and subdomains are allowed (e.g. shop.nike.com matches nike.com)
  • Wildcard domains are supported (e.g. *.nike.com)
  • localhost origins are allowed automatically during development
ℹ️

No API key needed

The widget only needs your appId. API keys are reserved for server-side SDK and REST API integrations where they can be kept secret.

How It Works

  • Shadow DOM — Styles are isolated. Your site CSS does not affect the widget, and widget CSS does not leak out.
  • Vanilla JS — No React, Vue, or other framework required. Works on any website.
  • CDN-ready — The bundle is self-contained (~12KB gzipped) and can be served from any CDN.

Next Steps

Last updated on