Skip to main content

Overview

Both <tavus-widget> and <tavus-embed> support two-way communication with the host page:
  • Element → page: the element dispatches CustomEvents (with bubbles: true and composed: true) for conversation lifecycle, tool calls, and protocol messages.
  • Page → element: the element exposes an imperative API at element.tavus for starting, ending, and messaging the conversation.
CDN consumers use plain DOM APIs - no extra bundle needed. npm consumers can use the typed TavusIntegration helper exported from @tavus/widget and @tavus/embed.

Events

Listen on the element itself, or on document (events bubble out of the shadow DOM):
tavus:protocol-message carries the raw Interaction Events protocol - detail.event_type values such as conversation.utterance, conversation.tool_call, conversation.started_speaking, and conversation.stopped_speaking match the schemas documented there. For speaking state, check detail.properties.role ("user", "pal", or legacy "replica"). See Started/Stopped Speaking Event.
Magic Canvas card taps are not emitted as tavus:* host events - they are delivered to your conversation webhook as canvas.interaction events. See Canvas interactions.

Imperative API

The element exposes its conversation controls on element.tavus:
element.tavus is attached once the element has mounted and its configuration has loaded. Wait for the element to render (or for a tavus:state-change event) before calling into it.

Interactions

sendMessage accepts the same interaction shapes as the Interactions Protocol:

TavusIntegration helper (npm)

npm consumers get a typed wrapper around the element from the same package as the registration side effect:
The helper looks up the element by tag name in the DOM, so construct it (or make the first call) after the element exists on the page.
TavusIntegration is bundled into the ESM builds of @tavus/widget and @tavus/embed - no extra install. The CDN (IIFE) build stays a pure side-effect drop-in; CDN pages use the DOM APIs above instead.