How to add it
Add your agent to any website using the Configure Widget dialog in your agent’s settings. Step 1: Open the agent settings by clicking the gear icon in the top-right of the agent editor.



Widget types
Each embed widget is either a voice widget or a chat widget — pick the type in the Configure Widget dialog. Both types support all three embed modes.
How chat conversations behave:
- The conversation starts when the visitor opens the chat (clicks the chat button) — the agent greets them first. Page loads alone never start a conversation.
- A chat session lasts up to 1 hour. When it expires, the visitor is offered a Start new chat button, which begins a fresh conversation.
- Reloading the page starts a fresh conversation on the next open — chat history isn’t carried across page loads.
- Each conversation counts once toward the embed token’s usage limit, same as one voice call.
- Chat conversations appear in your agent’s call history with a full transcript.
Embed modes
Prerequisites
These apply to all three modes:- Voice widgets: serve your page over HTTPS or from
http://localhost. Browsers refuse microphone access on plain HTTP origins orfile://. Chat widgets have no microphone requirement, though HTTPS is still recommended. - If you set Allowed Domains in the dashboard, include your test origin (e.g.
localhost) — otherwise the widget’s requests are rejected. Leave the list empty to allow all domains. - The embed snippet you copy from the dashboard is a single
<script>tag that loadsdograh-widget.jsasynchronously. The widget auto-initializes once it loads and exposeswindow.DograhWidget. Code that registers callbacks must wait for the widget to be available.
Pass context to the agent
Your page usually knows something about the visitor — their name, plan, cart value, the article they were reading. Pass it along and your agent can use it from the first word. The snippet you copy from the dashboard carries adata-dograh-context attribute — a JSON object of details about the visitor. The snippet is a small bootstrap function: js is the widget <script> element it creates, and the context is attached to that element before it is added to the page. The relevant part of the generated snippet looks like this (keep the generated js.src value, which contains your embed token):
JSON.stringify(...) in the generated snippet, for example:
{{initial_context.<name>}}:
Update context after the page loads
The attribute is fixed at page load, which doesn’t fit a single-page app — the visitor logs in, changes route, or fills a cart long after the snippet ran. For that, callsetContext():
getContext() returns the current set.
Context is read when a conversation starts, so setContext() applies to the next conversation — calling it mid-call or mid-chat doesn’t change the one in progress (the widget logs a console warning if you do). For chat widgets, “next” includes the fresh conversation started by Start new chat after a session expires.
The widget script loads asynchronously, so
window.DograhWidget may not exist yet when your app’s code first runs. Call setContext() from an event that fires after load — a window.load listener, or a user action like clicking your own “Chat with us” button. See Lifecycle callbacks for the same timing rule.data-dograh-context for what the page knows at render, setContext() for what it learns later. They merge, and setContext() wins on a repeated name.
Limits, applied per conversation: up to 50 variables, 64 characters per name, 2000 characters per value, and 8 KB in total. Anything past a limit is dropped and the conversation still starts. The names provider and runtime_configuration are reserved and ignored.
Floating Widget

- Voice: clicking the button (microphone icon + text) starts a call; clicking again ends it. The button auto-updates its label and color across the call lifecycle: configured text → “Connecting…” → “End Call” → “Retry” on failure.
- Chat: clicking the button (chat icon + text) opens a chat panel anchored to the same corner; the agent greets the visitor and the conversation happens in the panel. Clicking the button (or the panel’s ×) closes the panel without ending the conversation — reopening shows the same transcript.
Inline Component

<div> you place in your page.
- Voice: a status panel (status icon + status text + CTA button). Status changes update the panel in place.
- Chat: a call-to-action screen first; clicking the button replaces it with a chat panel that fills the container. No extra JavaScript is needed.
Plain HTML
Place a container<div> where you want the widget to render. The widget auto-attaches to it.
React
Because React mounts after the widget script may have already loaded, integrate viainitInline on first mount and refresh on remount. Poll for window.DograhWidget to handle the async script load.
Headless Mode

JavaScript API (voice widgets)
All
on* setters are single-listener — calling the same one again replaces the previous handler.
JavaScript API (chat widgets)
In chat mode
start() aliases startChat() and end() is a no-op teardown (chat sessions need none), so generic snippets keep working. Sends are serialized — sendMessage while a reply is pending (waiting) resolves to null.
About timing. The widget script loads asynchronously, so
window.DograhWidget may not exist at the moment your inline <script> first runs. The examples below assume window.DograhWidget is already available when registration runs. To guarantee that:- Vanilla JS: wrap your registration code in
window.addEventListener('load', () => { /* register here */ }). - React: inside
useEffect, register immediately ifdocument.readyState === 'complete', otherwise add a one-timewindow.loadlistener that registers on fire. - Click handlers that call
start()/end()don’t need a guard — by the time a user clicks, the widget has long since loaded.
Vanilla JS
React + TypeScript
start() must run inside a real user-gesture handler (click, touchend, etc.). Browsers refuse to grant microphone access to scripts that request it outside of one — calling start() from a setTimeout or on page load will fail with a permission error.Lifecycle callbacks (all modes)
Theon* callbacks in the Headless JavaScript API work in all three embed modes, not just Headless. Use them for analytics or to trigger UI in the host page even when the widget is rendering its own UI (Floating or Inline). The call callbacks (onCall*) fire for voice widgets; for chat widgets use onMessage and onChatStateChange the same way.
onCallConnected and onCallDisconnected only fire when the call actually establishes a media connection — failed-to-connect attempts (e.g. denied mic, network failure) don’t trigger them, so analytics stay clean.