App Views (Admin & User)
This note explains how SAALT Apps expose UI views for admins and end users. It is based on the existing translator App (user view) and Apps like dynaflow-whatsapp that ship an admin view.
How views fit into an App
- Each App can optionally expose two chat pages that the SAALT host renders inside its UI: an admin view for configuration and a user view for the end-user chat experience.
- SAALT learns which views you provide from
app/routes/meta.ts. SethasAdminChatPage/hasUserChatPagetotrueto opt in, otherwise the host will never request those routes. - Views are iFramed within SAALT and are required to respond with a renderable page.
- Each request includes a bridge authentication header. This token can be used to make requests back to SAALT via the bridge.
This example shows a transcription App fully integrated into the chat window:
Code
Routing conventions
- User view: served at
/user/:agentId. - Admin view: served at
/admin/:agentId. - The
agentIdroute param identifies which agent (and therefore which config/context) the page should use.
The /user/:agentId and /admin/:agentId conventions above are for agent-scoped Apps. Standalone Apps are served without an agentId param: SAALT Core renders the App's user surface at the top-level /plugin/{id} route and its admin/config surface via an iframe, and the bridge is created without agentId. The bridge.llm.generateText({ ..., agentId }) action example below stays correct — agentId still lives inside the LLM params.
User view example (translator App)
Path: plugins/translator/app/routes/user/index.tsx with hasUserChatPage: true. (Repo folder name is still plugins/ — only the user-facing term has changed.)
- Exports a
loaderto readagentIdand anactionthat usesbridge.llm.generateTextto perform the translation. - The UI is a React component that renders inside SAALT, submits via
<Form method="post">, and reads results withuseActionData. - Because
bridgeMiddlewareinjects the bridge, the action can call any SAALT capability (LLM, tools, config) on behalf of the agent.
Code
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: either use a middleware to inject the bridge into the context or create it on the page directly.
- Handle data with
loader(read agent-scoped data) andaction(process form submissions). - Render the UI using your preferred components; submissions go through React Router's
<Form>so the host can hydrate state. - Test inside SAALT: the host will request your route only if the corresponding meta flag is
true, passingagentIdand auth headers so the bridge can call SAALT services.
With those pieces in place you can tailor both admin configuration pages and user-facing chat experiences directly inside your App.