> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://developers.deepgram.com/docs/browser-agent-widget/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.deepgram.com/_mcp/server. # Widget Embedding Guide > How to embed the Deepgram voice agent widget on any web page. Covers CDN and ES module installation, six layout modes, theming with design tokens, callbacks, and programmatic teardown. Add a voice agent to any website. No framework required, no build step needed. The widget ships as a self-contained bundle with its own Preact runtime (\~160KB gzipped), six layout modes, and full design-token theming. It works from a CDN or as an ES module, and tears down cleanly for single-page apps. > **Info** > > The widget bundles everything internally. No React or build tooling required. For React-native integration, see [React UI Components](/docs/browser-agent-react-ui). ## Quick Start ### Install ```bash npm install @deepgram/agents-widget ``` ### ES Module ```javascript import { init } from "@deepgram/agents-widget"; const teardown = init({ tokenFactory: () => fetch("/api/deepgram-token").then((r) => r.text()), agent: "YOUR_AGENT_ID", layout: "sidebar", }); // Call teardown() to unmount the widget and clean up ``` Replace `YOUR_AGENT_ID` with a [Reusable Agent Configuration](/docs/reusable-agent-configurations) UUID, or pass an inline agent config object instead. See [Agent Configuration](/docs/browser-agent-overview#agent-configuration) for both patterns. ### CDN Load the widget from `cdn.deepgram.com` for a no-build path: ```html ``` The `latest` segment in the URL above is replaced with the current pinned version when this page loads, so the snippet you copy targets a specific build, not a moving release pointer. ### Self-hosted UMD The package ships a UMD bundle at `dist/widget.umd.js` for ` ``` > **Warning** > > Never include your API key in client-side code. Use `tokenFactory` to fetch short-lived tokens from your server. The `apiKey` option exists only for local development. ## Layouts The widget ships with six layout modes. Set the `layout` option to choose one. ### sidebar (default) A panel that slides in from the edge of the screen. Toggled by a floating action button (FAB). ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "sidebar", placement: "bottom-right", defaultOpen: false, dismissible: true, }); ``` ### floating A FAB button that reveals a floating overlay panel. ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "floating", placement: "bottom-right", }); ``` ### inline Mounts directly into an existing DOM element. No FAB, no overlay. ```html
``` ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "inline", containerId: "agent-container", }); ``` ### embedded Full-width card with configurable aspect ratio. Includes the conversation transcript. Ideal for landing pages and product demos. ```html ``` ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "embedded", containerId: "agent-embed", theme: { aspect: "16 / 9", minHeight: "400px", }, }); ``` ### button A single talk button -- press to start, press again to stop. Minimal footprint. ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "button", placement: "bottom-right", }); ``` ### orb The Deepgram animated hoop visualization with start/stop controls. Audio-reactive -- the orb responds to input and output volume in real time. ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "orb", placement: "bottom-right", }); ``` ## Placement For layouts with a FAB (`sidebar`, `floating`, `button`, `orb`), set where the button appears: ```javascript placement: "bottom-right" // default // Options: "bottom-right", "bottom-left", "bottom", // "top-right", "top-left", "top" ``` ## External Trigger Button To use your own button instead of the built-in FAB, pass its element ID: ```html ``` ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", layout: "sidebar", buttonId: "my-agent-btn", }); ``` To toggle the widget programmatically from anywhere: ```javascript document.dispatchEvent(new Event("dg-agent-toggle")); ``` ## Features Toggle UI features on or off: ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", showTranscript: true, // conversation history (default: true) showMicToggle: true, // microphone mute button (default: true) showSpeakerToggle: true, // speaker mute button (default: true) showTextInput: true, // text input field (default: true) }); ``` ## Text Customization Override labels and placeholder text: ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", text: { name: "Aria", startLabel: "Talk to Aria", stopLabel: "End conversation", connectingLabel: "Connecting...", inputPlaceholder: "Type a message...", emptyStateHint: "Press start to begin talking.", }, }); ``` ## Agent Overrides Override the agent's system prompt or greeting for this session without changing the agent configuration in the Deepgram console: ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", overrides: { systemPrompt: "You are a customer support agent for Acme Corp.", greeting: "Hi! How can I help you with your Acme account?", }, }); ``` ## Callbacks Listen to agent lifecycle events for analytics, logging, or UI integration: ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", on: { onConnect: () => console.log("Connected"), onDisconnect: (reason) => console.log("Disconnected:", reason), onError: (err) => console.error("Error:", err), onMessage: (msg) => console.log(`${msg.role}: ${msg.content}`), onAgentStartedSpeaking: (msg) => console.log("Agent speaking"), onFunctionCallRequest: (msg) => console.log("Function call:", msg), onAgentError: (msg) => console.error("Agent error:", msg), onReconnecting: (attempt, delayMs) => console.log(`Reconnecting (attempt ${attempt}, ${delayMs}ms)`), }, }); ``` | Callback | Fires when | | ------------------------ | ----------------------------------------------------------- | | `onConnect` | WebSocket connection opens | | `onDisconnect` | Session ends (user or server side) | | `onError` | SDK-level error occurs | | `onMessage` | Any conversation turn (user or assistant text) | | `onAgentStartedSpeaking` | Agent begins speaking; includes latency metrics | | `onFunctionCallRequest` | Agent requests a client-side function call | | `onAgentError` | Agent-reported error (distinct from SDK errors) | | `onReconnecting` | Reconnect attempt starts; receives attempt number and delay | ## Color Scheme Control how the widget adapts to light and dark mode: ```javascript // Automatic -- follows prefers-color-scheme (default) colorScheme: "auto" // Force light or dark colorScheme: "light" colorScheme: "dark" // Class-based -- for CSS framework integration (e.g., Tailwind dark mode) colorScheme: { mode: "class", darkSelector: ".dark", // default lightSelector: ".light", // default } ``` The class-based option watches for a CSS selector on any ancestor element. Use it when the host app controls theme via a class on `` rather than OS preference. ## Theming Customize the widget's appearance by overriding design tokens. Each property maps to a CSS custom property on the widget root element (`[data-dg-agent]`). Set a token here to override the built-in adaptive default in both light and dark modes. ```javascript init({ tokenFactory, agent: "YOUR_AGENT_ID", theme: { // Accent primary: "#6366f1", primaryHover: "#4f46e5", primaryActive: "#4338ca", onPrimary: "#ffffff", // Surface background: "#ffffff", backgroundRaised: "#f9fafb", backgroundInput: "#ffffff", backgroundHover: "#f3f4f6", backgroundActive: "#e5e7eb", // Text text: "#111827", textMuted: "#6b7280", // Chrome border: "#e5e7eb", error: "#ef4444", overlay: "rgba(0, 0, 0, 0.25)", // Messages userMessageBackground: "#f3f4f6", userMessageBorder: "#e5e7eb", // Radius panelRadius: "16px", buttonRadius: "9999px", inputRadius: "8px", messageRadius: "12px", // Structural fabSize: 56, padding: "16px", font: "Inter, system-ui, sans-serif", }, }); ``` To override only one color scheme, skip the `theme` option and write CSS directly: ```css @media (prefers-color-scheme: dark) { [data-dg-agent] { --dg-va-bg: #0d1117; } } ``` ### Embedded Layout Tokens The `embedded` layout supports additional sizing tokens: ```javascript theme: { aspect: "4 / 3", // CSS aspect-ratio (default: "4 / 3") minHeight: "320px", // default: "320px" maxHeight: "80vh", // default: "80vh" } ``` ## Full Configuration Reference ```javascript init({ // -- Auth (one required) -- apiKey: "...", // Development only tokenFactory: () => Promise