Skip to main content
The voice widget puts a call button on your site. A visitor clicks it, grants microphone access, and is talking to your agent over WebRTC — no phone number involved.
The widget is fully self-contained. The script loads everything it needs (React, ReactDOM, and the LiveKit browser client) from the CDN at runtime, so it works on a plain HTML page with no build step and no dependencies of your own.

Quick start

Paste this before the closing </body> tag of any page, replacing the agent UID and public key with your own:
That is the whole integration. The dashboard generates this snippet pre-filled for you under any agent’s Widget tab.
Always set assistant-id and public-api-key explicitly. If you omit them the widget falls back to a demo agent and demo key baked into the package — your visitors would connect to a demo bot instead of yours.

Complete working page

Attributes

assistant-id and public-api-key are marked required because you should always set them, not because the widget errors without them — it silently falls back to demo values instead.

Display types

The default. The widget renders as a compact launcher that stays collapsed until the visitor clicks it, then expands into the call panel. Best for adding a call option to an existing page without changing the layout.
theme, position, and auto-start are accepted by the current build but have no effect on rendering. They appear in the package README, so they are easy to find and easy to trust — but setting them changes nothing today.

Using it in React

The widget is a plain custom element, so it works in React — but it needs one extra step that plain HTML does not.
The widget scans the page for openmic-widget elements exactly once, when the script loads. In a React app your element is rendered after that scan, so a bare copy-paste of the HTML snippet silently does nothing — the console logs No widget elements found. Load the script from an effect, after the element is mounted, as shown below.
window.OpenMicWidget.init() re-scans the whole page. If you render several widgets, mount them together rather than one at a time, or an already-initialized widget can be rendered twice.

TypeScript

openmic-widget is not a known JSX element, so declare it once:
Load the widget from the CDN script above in every environment, React included. It ships as a browser bundle rather than an ES module, so there is no component to import and no package to add to your dependencies.

Requirements and limitations

The widget does not work when served from localhost or 127.0.0.1. On those hostnames it tries to load its stylesheet from a relative path that does not exist in your project. The stylesheet fails, initialization aborts before the widget renders, and the console shows Failed to initialize.To test locally, serve the page on a hostname that is not localhost — your machine’s LAN IP (http://192.168.1.x:3000) works, as does any tunnelling tool that gives you a public hostname. Deployed sites are unaffected.
Requires a modern browser (Chrome 60+, Firefox 55+, Safari 12+, Edge 79+) with WebRTC and microphone support. Browsers only grant microphone access on secure origins, so the page must be served over HTTPS in production. The visitor sees a permission prompt on the first call.
If they are not already present on the page, the widget loads React 18, ReactDOM 18, and livekit-client from unpkg.com, plus its own stylesheet. If your site sets a Content Security Policy, allow unpkg.com for script-src and style-src, and the OpenMic API and LiveKit hosts for connect-src.Pages that already run React are fine — the widget reuses the React already on the page and otherwise loads its own copy.
The snippets above use @latest, which always serves the newest release. For production you may prefer to pin an exact version so a new release cannot change behaviour without you:

Troubleshooting

The widget logs every step of startup to the browser console, prefixed with a microphone emoji. Opening the console is the fastest way to see how far it got.