Frontend Integration Guide¶
ForgeOS treats frontend wiring as part of the generated app contract.
The goal is for an agent to answer: which route calls which command, which query powers which view, and which liveQuery updates which screen?
Expected structure¶
web/
src/ or app/
lib/forge.ts
composables/forge.ts # Nuxt/Vue
plugins/forge.client.ts # Nuxt browser provider
plugins/forge.server.ts # Nuxt SSR provider
components/**
src/forge/_generated/
client.ts
react.ts
vue.ts
frontendGraph.json
capabilityMap.json
The local bridge file should import generated Forge hooks or composables and expose one stable path to app components.
Provider¶
Mount ForgeProvider near the root of the web app.
Local development usually uses dev auth:
<ForgeProvider
baseUrl={forgeUrl}
devAuth={{
userId: "dev-user",
tenantId: "dev-tenant",
role: "owner",
}}
>
{children}
</ForgeProvider>
Production apps should use the configured auth mode and pass bearer tokens through the client transport.
Nuxt apps install the Forge Vue plugin from web/plugins/forge.client.ts and web/plugins/forge.server.ts, then read runtimeConfig.public.forgeUrl, overrideable through NUXT_PUBLIC_FORGE_URL.
Hooks¶
Use generated hooks instead of raw fetches:
const tickets = useLiveQuery("liveTickets", {});
const createTicket = useCommand("createTicket");
const ticket = useQuery("getTicket", { id });
This keeps UI calls visible to frontendGraph.json and capabilityMap.json.
Nuxt/Vue components use generated composables:
<script setup lang="ts">
const tickets = useForgeLiveQuery("liveTickets", {});
const createTicket = useForgeCommand("createTicket");
</script>
Capability map¶
Inspect the UI/backend connection:
forge inspect frontend --json
forge inspect capabilities --json
forge do connect-ui --json
Capability map diagnostics help find:
- runtime entries with no UI caller;
- UI calls to missing commands or queries;
- raw runtime fetches;
- missing
ForgeProvider; - bridge files not using generated hooks;
- routes that should subscribe to liveQuery but do not.
Anti-patterns¶
Avoid:
fetch(`${apiUrl}/commands/createTicket`, { method: "POST" });
Prefer:
const createTicket = useCommand("createTicket");
await createTicket.mutate({ title });
Avoid importing generated files throughout the app. Keep generated imports behind web/lib/forge.ts so agents have one bridge to inspect.
Local dev¶
forge dev
forge dev --once --json
Open the web URL for the app. The API URL is for JSON runtime calls and health checks.
Add a frontend shell¶
forge make ui --framework vite --dry-run --json
forge make ui --framework vite --yes
forge make ui --framework nuxt --dry-run --json
forge make ui --framework nuxt --yes
forge generate
forge inspect frontend --json
For a resource with UI:
forge make resource notes --fields title:text,status:enum(open,done) --with-ui --dry-run --json
Verify frontend wiring¶
forge dev --once --json
forge inspect capabilities --json
forge ui smoke --json
forge verify --standard