Web SDK Overview
@appilots/web-sdk puts the Appilots agent inside a web application. The agent reads the page, navigates between routes, fills forms, and presses buttons, all inside the user's browser tab and next to a chat the user talks to.
It works with any framework. The SDK reads the page through the DOM and its accessibility tree, not through a framework's internals, so the same runtime drives a React, Vue, Svelte, or hand-written app. React gets a thin binding (@appilots/web-sdk/react) with a ready-made chat widget. Every other framework uses the runtime class directly.
How it differs from the React Native SDK
The agent, the backend, the dashboard, and the API are the same. The client side differs in a few ways:
React Native (@appilots/sdk) | Web (@appilots/web-sdk) | |
|---|---|---|
| Reads the screen through | React's component tree | The DOM and ARIA (roles, accessible names, states) |
App map built by appilots sync from | React Navigation in your source | React Router screens plus a declared manifest (platform: "web") |
| Screen tracking | AppilotsNavigationContainer | Automatic, from the URL and the routes you declare |
| Chat languages | en, pt-BR, es, fr | en, pt-BR |
| Dashboard personalization (theme, assistant name) | Applied automatically | Not applied — style the widget with its props |
Because the SDK reads the accessibility tree, an accessible page is a page the agent can operate. Controls with a visible label or aria-label, real <button> and <input> elements, and proper roles are what the agent relies on. See Markup & actions for what to add when the defaults are ambiguous.
What you need
- A project in the dashboard with a model configured. Use a separate project per app, and don't share one between your mobile and web apps:
appilots syncreplaces the project's app map. - Two keys for that project (see Key scopes):
- an SDK key, which goes into the browser;
- a publish key, which is private and used only by the CLI.
reactandreact-dom18 or newer if you use the React binding.
Known limitations
The web surface is published and used in production, but its DOM layer still has gaps tracked in #544. Until they close:
- Plain elements with click handlers are not seen. Only
<button>, links, interactiveroles and inlineonclickattributes count as pressable. Frameworks attach listeners programmatically, so<div onClick>cards, rows, tabs and chips are invisible. Use real buttons orrole="button"+tabindex="0". - The synthetic click is a plain
MouseEventsequence with no coordinates and no hover phase. Components that readpointerId(Radix/shadcn, dnd-kit), position from the event, or open on hover may not react. - Only declared modals block presses. A press under a sticky header, toast, cookie banner or roleless overlay can be swallowed while the SDK reports success. Mark blocking overlays
role="dialog"+aria-modal="true", or non-blocking onesdata-appilots-skip. - Rich-text editors are not supported.
contenteditableis written viatextContent, which Slate, Lexical, ProseMirror and Quill ignore. Use<input>/<textarea>for fields the agent should fill.
Pages in this section
- Quick start — install, publish the app map, and mount the chat.
- Runtime & provider — every configuration option, the runtime API, and the hooks for a custom chat.
- Chat UI —
AppilotsChatFab(floating or docked side view) andAppilotsChat. - Markup & actions — the
data-appilots-*attributes, what the agent sees, and how actions run in the browser.
Voice dictation has its own guide: Voice input.