adras-action: show your own components in the chat
The widget is one script tag on your site. Wrap any component in <adras-action> and the assistant can open it during the conversation: a calculator, or a booking form already filled in. The component stays yours, in your framework, with its own state and handlers. The widget hides the wrapper when the page loads and pins it beside the chat when the assistant decides it answers the visitor's question.
Install
<script defer src="https://plugin.adras.ai/plugin.js" data-org="YOUR_ORG"></script>
data-org is your organisation id from the Website integration page of the dashboard. The widget mounts itself. Set data-auto-init="false" and place <adras-plugin org="YOUR_ORG"></adras-plugin> yourself if you need to choose where it sits.
Wrap a component
<adras-action
name="mortgage"
description="When the visitor asks about a mortgage, a loan payment or the rate. Shows the calculator filled in with their amount and term."
style="display:none"
>
<MortgageCalculator />
</adras-action>
Put it anywhere in the page, in any framework. The children render as usual. The widget never copies, serialises or reparents them; it only changes the wrapper's display and position.
| Attribute | Rule |
|---|---|
name |
Required. Unique on the page. Short and lowercase, like mortgage or book-visit: the visitor sees it on the tab that reopens the component. A second element with the same name replaces the first. |
description |
Required. At most 256 characters. The assistant decides from this text alone whether to show the component, so write it like a tool description: what it shows and when to show it. |
content |
Optional. content="off" stops the widget from sending a text digest of the wrapped component to the assistant. Use it when the component shows the visitor's own data. |
style="display:none" |
Recommended. Hides the component before the script loads. The widget sets the display itself from then on. |
Writing the description
The assistant sees the name, the description and a digest of the component's text. It picks a component when the visitor's message matches the description, so name the situation rather than the widget.
Works: When the visitor asks about a mortgage, a loan payment or the rate. Shows the calculator filled in with their amount and term.
Rarely fires: Mortgage calculator
The limit is 256 characters. Above it the server rejects the whole registration, so none of the page's components register, not only the long one. The widget prints the server's reply in the browser console when that happens.
The box your component gets
The widget pins the wrapper into a box of its own and scrolls anything taller. It does not resize your component; your component sizes itself to the box.
| Viewport | Where | Box |
|---|---|---|
| 640 px wide and up | beside the chat window | 16:10, 1.91 chat widths wide: about 856 × 535 px on a 1440 × 900 screen |
| under 640 px | inside the chat sheet, under the messages | the sheet's width, up to 50% of its height |
The wrapper is a CSS container (container-type: inline-size) with a definite width and height, so size against it:
- Percentages and
height: 100%fill the box. - Container queries (
@container (min-width: 600px)) andcqwunits switch layouts inside it. vh,dvh,vwand media queries still measure the browser window, soheight: 100vhoverflows a 535 px box. Avoid them inside the component.position: fixedinside the wrapper is re-based to the box by containment, so a modal inside the component covers the component, not the page.
Content taller than the box scrolls inside it. The visitor sees the top first, so put the figure and the button where they show without scrolling.
Frameworks
React with TSX needs the tag declared once: declare namespace JSX { interface IntrinsicElements { "adras-action": any } }.
Vue warns about unknown tags unless you mark it as a custom element: compilerOptions.isCustomElement = (tag) => tag.startsWith("adras-").
Svelte needs nothing.
Server rendering (Next, Nuxt, SvelteKit, Remix) renders the tag itself without harm. The component inside must survive rendering without a browser, or be client-only: dynamic(() => import("./Calc"), { ssr: false }) in Next, <ClientOnly> in Nuxt, {#if browser} in SvelteKit.
The registry is the live DOM of the page the visitor is on. A component mounted only on /pricing exists for the assistant only while the visitor is on /pricing; a component in the root layout is available everywhere. Mounting and unmounting update the registry during the conversation.
What the assistant receives
For every <adras-action> on the page the widget sends the name, the description and, unless content is off, a markdown-like digest of the component: headings, text, list items, table rows and controls (buttons, links, inputs, images), cut at 1000 characters or 400 nodes. It resends the list when a component appears or disappears. Names and descriptions are read from the elements each time.
Check the integration
- Load the page and open the browser console. The widget logs a
[adras-plugin]warning for a duplicate name, a description over 256 characters or a rejected registration. - In the Network tab,
POST /chat/actions/registerreturns 200 and its body lists your components. - Ask the widget the question from your description. The component opens beside the chat.
- Narrow the window under 640 px, or open the page on a phone, and ask again. The component opens inside the chat sheet.
For agents and scripts
This page is also served as plain markdown at https://adras.ai/docs/actions.md and is listed in https://adras.ai/llms.txt.