Embedding Agents as Widgets
Xagent can expose an agent through an embeddable widget flow for website or product integration.How widgets work
The widget flow is guest-oriented. A client:- Authenticates a guest against a specific agent
- Receives a guest chat token
- Uploads files if needed
- Creates a widget chat task
- Continues the session over the public chat runtime
Agent-level widget controls
Agents now expose widget-related settings:widget_enabledallowed_domains
Domain allowlist
The widget authentication flow validates the request origin against the agent’s allowed domains. Use this to restrict where the widget can be embedded:- Exact domains
- Subdomains
*for unrestricted access, only if you deliberately want that behavior
Recommended setup
For a production widget agent:- Use a focused prompt
- Keep tools narrow and predictable
- Add safe suggested prompts
- Restrict allowed domains
- Test guest file uploads and session continuity
Opening the chat from your page
The widget script,widget.js, adds a chat button and a chat panel to your page. Once it has loaded, your own page code can open that panel, and can optionally start a new conversation with a message you choose. A typical use is a button such as “Ask about pricing” that hands a prepared question to the agent.
Example
The page below embeds the widget and has two buttons. The first opens the chat with a prepared question. The second only opens the chat.widget.js tag. The tag above shows only the attributes needed for this example.
Calling XagentWidget.open
options is optional. It is an object with one key:
message(string, optional): the text to send as the first message of a new conversation.
XagentWidget.open()opens the chat panel and sends nothing.XagentWidget.open({ message })opens the chat panel and starts a new conversation. If a conversation is already in progress, it is left behind and the new conversation starts instead.messageis sent as the first message of the new conversation, and the agent starts answering it.- Every call takes effect, including when the panel is already open. The panel does not need to be closed first. If a visitor clicks a second button while the chat is open, the panel stays open and the second message starts another new conversation. Calls that arrive close together are covered under “Repeated and overlapping calls” below.
XagentWidget exists only after widget.js has loaded, so code that runs before the script has loaded cannot call it. Calling open from click handlers, as in the example, avoids this. If the page has no active widget, for example because the embed tag is missing its widget key, open does nothing except write a warning to the browser console.
Message rules
Leading and trailing whitespace is removed frommessage. What remains must not be empty and must not be longer than 2000 characters.
If message is given but does not meet these rules, or is not a string, the panel still opens, no message is sent, and the browser console shows this warning:
message, or with message set to undefined, only opens the panel and shows no warning. Options other than message are ignored and are named in a browser console warning. Passing something that is not an object also opens the panel without sending a message, with a console warning.
Repeated and overlapping calls
- Each call with a valid message starts a new conversation. The conversation that was replaced is not stopped: if the agent was still answering in it, the answer is completed in the background. The visitor cannot return to the earlier conversation from the chat panel.
- Each call with a valid message also starts a new agent run, which counts toward usage in the same way as a conversation the visitor starts in the panel. The widget itself does not limit how often
opencan be called. - If the chat has not finished loading, the message is held and sent as soon as the chat is ready. When several calls are made before that, only the last message is sent.
- If the chat is busy, for example because an earlier call is still starting its conversation or a message the visitor typed is still being sent, the message waits for its turn. Only one message can wait. A newer call replaces the one that is waiting, so when a visitor clicks several buttons quickly, the messages in between are skipped.
opendoes not retry a message. If the chat cannot start the new conversation or cannot deliver the message, the message is dropped. The chat then shows the same error notice it shows when the visitor’s own attempt fails in the same way, and a warning is written to the browser console.- Starting a new conversation discards any text the visitor typed into the chat input but did not send.
- After
openhas been called with a valid message, that widget no longer sends the message set with itsdata-initial-messageattribute. Callingopenwithout a message leaves it unchanged. If the widget had already sent thedata-initial-messagetext to the chat, for example because the panel opened a moment earlier oropen()was called without a message just before, that text is not withdrawn: the chat starts a conversation with it as usual, and the message fromopenthen starts a new conversation that replaces it. - If the page has more than one widget, the call goes to the most recently initialized one that is still on the page.
Widget vs share link
Use a widget when:- The agent is embedded into your product or site
- You need origin checks
- The conversation is part of a product experience
- You want a public standalone entry point
- The interaction is link-driven rather than embedded

