Embed a support widget as a launcher, page, or pane
Heliune widgets are workspace objects. Install copies a floating script or a page/pane iframe; visitor messages open an inbox thread and can run an attached flow.
A Heliune widget is a workspace object, not a second inbox. You draft it in the widget builder or from the builder agent in the rail. Install copies a snippet. Visitor messages open a widget-channel thread in the same inbox the team already works.
The live frame at /widget/{id} is noindexed on purpose. Search should find this note, not the chat iframe. The public boot script is /widget/{id}.js. The mount id is heliune-chat. Appearance uses a token theme plus optional CSS on stable heliune-widget-* hooks — not the workspace chrome.
Three embed placements
Placement is a field on the same object. You do not create three widgets to get three shapes. You pick floating, page, or pane, then copy the matching snippet.
- Floating: a script before </body> mounts a launcher. The open window is a corner panel, a centered popup, or an edge sidebar.
- Page: an iframe for a dedicated support or help URL. Give the host a height; the chat fills it. The snippet uses a 640px minimum.
- Pane: the same iframe pattern for a product sidebar, help drawer, or in-app inbox. The snippet uses a 480px minimum.
What the launcher does
Floating has three display modes. Panel is the classic corner chat. Popup is a centered modal over a soft site overlay. Sidebar is an edge drawer from the launch side. Those modes are config, not three products. Page and pane skip the launcher and fill the iframe.
What the visitor sees before they type
Pre-chat can be empty, the greeting, greeting plus starter chips, or the first message step of the attached chat flow. An optional bubble sits outside the launcher with a hint and FAQ chips. Empty pre-chat means the thread stays blank until the visitor types. Flow-start means the live graph has already spoken as the widget name before anyone in the inbox is assigned.
Starter chips are suggested questions you edit on the widget. They are not a second knowledge base. Clicking one sends that text as the first visitor message and opens the inbox conversation like any other first line.
How a message reaches the inbox
Each visitor keeps a thread keyed by widget id and visitor id. The first message opens an inbox conversation on the widget channel. Later messages append to that conversation. If a live flow is attached, the graph can reply as the widget and record a flow run on that conversation.
A handoff node stops the graph and can set the conversation to pending. A person in the inbox then owns the thread. Draft and paused flows do not run on the public frame. Toggle Enabled before you expect the public frame to answer. Copying the Install snippet is the workspace onboarding signal that the embed left the builder.
The rail writes the same config
The rail’s create_widget and update_widget tools write the same config the manual builder edits: placement, display mode, greeting, starters, attached flow, theme, custom CSS, enabled. list_workspace shows the widget next to flows and automations so the agent does not invent a twin.
If the draft is wrong, open the widget builder. The object in the workspace is the source of truth. The public snippet reads that object. There is no hidden “AI widget” that bypasses install.
Plans and the mark
Free workspaces get one widget and show the Heliune mark. Starter gets three. Pro and Business are unlimited. Paid plans drop the mark. Voice minutes are unrelated to the embed: the widget can still open a thread on Free; listen / whisper / barge sit on Pro when the conversation becomes a LiveKit room.
What to install, and what not to index
Install is a copy button in the workspace. Floating injects the boot script. Page and pane inject an iframe pointed at the public frame. Do not paste the workspace URL. Do not ask search engines to index /widget/{id} — robots and metadata already noindex that route, the inbox, and /api.
If the snippet is on the site and Enabled is off, the visitor sees a dead frame. If Enabled is on and no live flow is attached, the first message still opens the inbox and waits for a person. That is a working install, not a failed bot.
A flow run is optional, not the product
Teams treat the embed as a bot and then wonder why the inbox is empty. The inbox is the product. The flow is an optional graph on that conversation. Message nodes speak as the widget. A condition branches. An action can call something you wired. Handoff is how a person takes the thread. Delay waits. None of that replaces resolve, snooze, or a supervisor on a later call.
If you want the first screen to be the flow, set pre-chat to the first live step. If you want a human to speak first, leave pre-chat empty and keep the flow off or paused. Both are valid. The snippet does not change. The workspace object does.
Read the install snippet once. If the widget id is wrong, the visitor is talking to a different object — or to nothing. The inbox will not show a thread for a snippet you never enabled.
Theme and CSS stay on the widget
The visitor should not see workspace chrome. Theme tokens and optional CSS on heliune-widget-* hooks style the frame they see. Do not paste your app’s global stylesheet into the snippet and hope. The host page keeps its own layout. The widget keeps its own tokens.
If you change greeting copy in the builder, the next visitor sees it. You do not redeploy your marketing site. That is the point of a workspace object: install once, edit the object, the public frame follows.
When a call starts from the same thread
The embed is chat. The workspace can still open a LiveKit room later. The supervisor who listens is looking at the same inbox conversation the widget opened. Do not install a second “voice widget.” Voice minutes are a plan entitlement, not a second snippet.
Defaults you get before you edit
A new object greets with “Hi — how can we help?”, launches as “Chat with us”, sits bottom-right, opens as a panel, uses pre-chat greeting, and turns the outside bubble on. The bubble message copies the greeting unless you write a shorter hint. FAQ chips on a new object start empty unless you already set starter prompts.
Position can move to another corner. Display mode can become popup or sidebar. Pre-chat can become none, starters, or the first live flow step. None of those changes create a second object. They patch the same config the public frame reads.
Enabled defaults on. That surprises people who copied a snippet from a draft they were still designing. If you do not want the public frame to answer yet, turn Enabled off before Install. Draft flows already stay quiet; Enabled off keeps the frame itself from looking live.
A worked install
Create the object. Set placement to pane if the chat belongs inside billing. Attach a live flow only if the first screen should speak as the widget name. Copy the pane iframe. Give the host at least 480px. Confirm the widget id in the src matches the object you just saved.
Open the public frame yourself. Send one line. The inbox should show a widget-channel conversation keyed by that widget id and your visitor id. If a live graph is attached, the flow run appears on the flow and as an inbox event. If handoff ran, status is pending. Reply from that row. Resolve when you are done.
If the inbox is empty, the id is wrong, Enabled is off, or you pasted the workspace URL. If the frame talks but no person can see it, you are looking at a different workspace than the one that owns the object. There is no hidden queue.
What Free versus paid changes on the frame
Free is one object and the Heliune mark. Starter is three objects and no mark. Pro and Business drop the cap. Builder-message budgets and voice minutes do not change the snippet. They change what the rail can draft and whether a later room can be supervised.
Custom CSS is still sanitized. Theme tokens merge; they do not import your app’s global sheet. If a color looks wrong, edit the widget theme, not the host. The visitor should not inherit workspace chrome because someone pasted a stylesheet into the snippet.
When you are choosing a vendor, ask one question: does the first visitor message open a conversation the same team can resolve, snooze, and later take as a LiveKit room? If the answer is “the bot handles it and we export a log,” you are not looking at this install.
What the snippet actually points at
Floating injects /widget/{id}.js with a data-heliune-widget attribute. Page and pane iframes hit /widget/{id}?embed=page or embed=pane. Floating can also load the frame with embed=floating. Do not rewrite those query values by hand and expect a fourth placement. The parser only accepts floating, page, and pane.
Install copy in the workspace already says the host steps: paste before </body> for floating; give the page iframe a height (the snippet’s min-height is 640px); size the pane host (480px). Toggle Enabled, then save. Copying the snippet is not a deploy. Saving Enabled is.
The public origin comes from the app URL. If that origin is wrong, the visitor loads a frame that is not your workspace. Check the src before you ship the marketing site. The inbox will not show a thread for a snippet pointed at the wrong host.
More guides
Voice rooms, inbox threads you can resolve, a flow and automation canvas, workspace run logs, and widgets in one Heliune workspace — with supervisor listen, whisper, and barge on the same call.
The Heliune builder agent sits in the workspace rail and drafts flows, widgets, automations, and dashboards you can still edit by hand.
Heliune guest call rooms are public /call/{room} pages. The customer copies no password. The agent copies a link. Listen, whisper, and barge stay on the same room.