An App can expose two views that SAALT renders inside its own UI: an admin view for configuration and a user view for the end-user chat experience. Views are ordinary web pages your App serves; SAALT iframes them and forwards an auth token so they can call back through the Bridge.
How views fit into an App
- SAALT learns which views you provide from
/meta: sethasAdminChatPageand/orhasUserChatPagetotrueto opt in — otherwise SAALT never requests those routes. - Each view is iframed inside SAALT and must respond with a renderable HTML page.
- Every request carries a Bridge auth header, so the view can make authenticated calls back to SAALT.
Code
Routing conventions
- User view — served at
/app/{id}/user/:agentId. - Admin view — served at
/app/{id}/admin/:agentId. {id}is your App's ownid, as declared in/meta— SAALT forwards the full prefixed path to your App, so define your routes at that full path (e.g. with theprefix()helper inroutes.ts).- The
agentIdroute param identifies which Agent (and therefore which config/context) the page uses.
The /app/{id}/user/:agentId and /app/{id}/admin/:agentId conventions are for agent-scoped Apps. Standalone Apps are served without an agentId: SAALT renders the user surface at the top-level /app/{id}/user route, and the Bridge is created without an agentId. Note that llm.generateText still takes an agentId inside its params even so — see the Bridge reference.
Migrating an existing App from unprefixed routes? See the 1.2 Migration guide.
User view example
A user view is a React Router route: a loader reads the agentId, and an action uses the Bridge (injected by your bridgeMiddleware) to do the work — here, a translation via llm.generateText.
Code
The UI is a React component that renders inside SAALT, submits via <Form method="post">, and reads results with useActionData. Because bridgeMiddleware injects the Bridge into the request context, the action can call any SAALT capability (LLM, Tools, config) on the Agent's behalf.
Building your own view
- Flip the meta flags in
app/routes/meta.ts(hasAdminChatPageand/orhasUserChatPage). - Add the route file at
app/routes/admin/index.tsxorapp/routes/user/index.tsx. - Wire the Bridge — inject it via
bridgeMiddlewareon the parent layout, then read it from context in yourloader/action. - Handle data with
loader(read Agent-scoped data) andaction(process form submissions). - Render the UI with your components; submit through React Router's
<Form>so SAALT can hydrate state. - Test inside SAALT — see Local development.
Next steps
- Bridge — the SDK your view calls.
- Tools — add a federated component to visualize a Tool result.
- Local development — run and register your App locally.