Widget API
/embed.js is self-contained and about eight kilobytes. It puts one object on the page, window.Huddles, and asks nothing of your framework.
Huddles.init(options)#
| Option | |
|---|---|
embedder | Required. Your app id. |
token | A token you already have, or — |
getToken | A function returning one (or a promise of one). Called when the iframe says it is ready. Omit both for walk-ins. |
position | 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'. Where the bar starts; a drag remembered per site still wins. |
lazy | Mount nothing until the first press of open(). |
mode | 'button': no bar, ever; presses grow a call card. Implied by Huddles.button(). |
The folds#
| Call | |
|---|---|
Huddles.open() | Unfold the island. |
Huddles.pop() | Grow to the panel: the whole product. Honours popOut. |
Huddles.close() | Fold to the bar. The iframe stays; nobody leaves anything. |
Huddles.move(where) | Any position value. The same thing a drag does. |
Huddles.diagnose()#
Returns a promise of { ok, checks } and logs the checks as a table: secure context, nested frames, the page's Permissions-Policy for microphone, camera and autoplay, whether this origin is registered on the app, whether the frame has mounted and said hello, and the last notice it showed. The first thing to run when something does not work — see troubleshooting.
The huddle button#
| Call | |
|---|---|
Huddles.button(node, { conversation, label? }) | Append a button to node for one thread. Returns the element. It polls the conversation's state, repaints itself, and grows the call card on a press. |
Huddles.call(conversation, rect?) | Start, or answer, that thread's huddle from a control of your own; the card grows from rect when given. |
In button mode pop() and move() do nothing: the card is the whole object, and it goes where the person drags it.
Huddles.init({ embedder: 'your-app-id', getToken: mint, mode: 'button' });
const b = Huddles.button(document.querySelector('#thread-header'), { conversation: thread.id });
b.classList.add('my-call-button'); // it is a plain <button>; style it as yoursWhat crosses the frame#
Nothing you need to handle. The widget and the app speak over postMessage, pinned to each other's origins: huddles:ready, huddles:token, huddles:anon, huddles:conversation go in; huddles:state, huddles:notice, huddles:pop, huddles:close come out and paint the bar. A JavaScript event API for your own UI (Huddles.on('huddle-started', …)) is sketched, not built.
huddles.space · Blog · For Mac · Premium · Terms · Privacy · © 2026 Huddles.Space