Skip to main content

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. Open agent settings Step 2: Scroll to the Add to Website section and click Configure Widget. Go to Add to Website Step 3: Enable embedding, add your website’s domain to Allowed Domains, choose a Widget Type (Voice or Chat) and an embed mode (Floating Widget, Inline Component, or Headless (Bring Your Own UI)), customize the button (position, color, text) if applicable, and click Save Configurations. Save configurations Step 4: Copy the generated embed code and paste it into your web page to test your agent. Copy deployment code

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 or file://. 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 loads dograh-widget.js asynchronously. The widget auto-initializes once it loads and exposes window.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.
Context Key names cannot contain dots, whitespace, pipes, or braces because those characters have structural meaning in template expressions. Invalid entries are dropped without preventing the conversation from starting.
The snippet you copy from the dashboard carries a data-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):
Because it’s built in JavaScript at page load, you can put anything your page knows in it — a logged-in customer’s name, their plan, cart contents. Replace the object inside JSON.stringify(...) in the generated snippet, for example:
Each key is then available in any node prompt as {{initial_context.<name>}}:
Values can be strings, numbers, booleans, or nested objects. This works for voice and chat widgets alike, and the values are recorded on the conversation so you can see what the agent was given.

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, call setContext():
Each call merges into the context already collected, so you can add details as they arrive and re-send a name to correct it. 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.
Use whichever fits: 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.
Context comes from the page, so a visitor can both read it and change it before it reaches your agent. Never pass secrets, and don’t let it gate what the agent will do or disclose — treat plan: "pro" as a hint for phrasing, not proof of entitlement. For data the agent must trust, pass an opaque id like customer_id and let Dograh fetch the real details from your API with Pre-Call Data Fetch.
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

Floating widget shown in the corner of a host page Renders a pill-shaped button anchored to a corner of the page.
  • 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.
Configure Button Text, Button Color, and Position (top/bottom + left/right) from the dashboard. The host page writes no JavaScript — pasting the embed snippet is the entire integration. If you want to subscribe to call lifecycle events (e.g. analytics), see Lifecycle callbacks below

Inline Component

Inline widget rendered inside a page section Renders a panel inside a <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.
Configure Button Text, Button Color, and Call to Action Text from the dashboard.

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 via initInline on first mount and refresh on remount. Poll for window.DograhWidget to handle the async script load.

Headless Mode

Headless widget driven by host-page UI In Headless mode the widget injects no UI of its own. You render whatever buttons, banners, or chat interfaces you want, and drive the agent through the JavaScript API.

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 if document.readyState === 'complete', otherwise add a one-time window.load listener 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)

The on* 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.