Display modes
The embed has one entry point — Roxels.start({ display }) — and three display values. The conversation, controller API, and event stream are identical across modes. Only the presentation differs.
Modal
A centered dialog that takes over the page. The participant focuses on the conversation; your page is dimmed underneath.
Roxels.start({ templateKey: "rk-...", display: "modal" });Use when:
- The conversation is the primary task right now.
- You want the polished, branded out-of-the-box look.
- The conversation is short-to-medium length and the user shouldn't be doing other things on your page during it.
Behavior:
- The widget shell mounts immediately.
- A background scrim dims the rest of the page.
- The user can close by hitting Esc, clicking the close button, or your code calling
Roxels.close(). - The widget includes a chat panel, a control bar, and the live document/form view if the template uses one.
Compact
A small panel anchored to the bottom-right of the page. The user can continue interacting with your page while the conversation runs.
Roxels.start({ templateKey: "rk-...", display: "compact" });Use when:
- The conversation is supplementary — for example, a guided walkthrough while the user fills out your form.
- The user should keep their place in your app.
- The conversation might be long-running and you want it tucked out of the way.
Behavior:
- Fixed position, bottom-right by default.
- Can be moved by the user.
- The chat panel and control bar collapse to a compact orb when minimized.
Headless
No widget at all. The iframe mounts invisibly, the call runs, and your code is responsible for the UI.
const call = Roxels.start({ templateKey: "rk-...", display: "none" });
call.on("voice_state", (state) => updateMyOrb(state));
call.on("chat", (msg) => appendToMyTranscript(msg));Use when:
- Roxels should feel native to your product.
- You have brand assets, motion systems, or interaction patterns that the widget doesn't match.
- You want a custom orb, a custom transcript, custom controls, or some combination.
- You're building a deeply integrated voice experience.
This is the recommended path for product teams shipping a voice-first feature where Roxels is the engine but not the chrome.
Read the full guide: Headless mode.
What's the same across all three modes
- The controller API (
call.pause(),call.muteMic(),call.on(...), etc.). - The full event stream (every event in Events fires for every mode).
- The session lifecycle (created, joining, connected, ending, ended).
- The template's behavior, voice, language, goals, skills, and outputs.
What differs
| Modal | Compact | Headless | |
|---|---|---|---|
| Roxels renders chrome | Yes | Yes | No |
| User can interact with your page | No (scrim) | Yes | Yes |
| Close button visible | Yes | Yes | You build it |
| Sizing | Fixed centered | Fixed corner | You decide |
| Chat UI | Built-in | Built-in | You build it |
| Document/form view | Built-in | Built-in | You build it |
Roxels.close() works |
Yes | Yes | call.hangUp() instead |
Switching modes
The display choice is made once, at the time you call start(). You can't toggle modal ↔ compact on a live call. If you need to change presentation, hang up and start a new call (the controller handles teardown cleanly).
Read next
- Headless mode — Deep guide, every method, every event, complete examples.
- Persistent launcher — How the floating button decides when to show.
- JS API reference — Every controller method.
- Events — Every event with payload shape.