Guide

Frontend

apps/dashboard is a Nuxt 4 app and the single deployable artifact: it serves the UI, the control plane, and authentication from one origin.

apps/dashboard is a Nuxt 4 app and the single deployable artifact: it serves the UI, the control plane, and authentication from one origin.

Module-per-feature layout

Application code lives under modules/<feature>/ rather than Nuxt's default flat directories. Each feature is a real Nuxt module: its index.ts registers its own components/, composables/, and utils/ directories, and Nuxt discovers it by scanning modules/, so nothing has to be listed in nuxt.config.ts. apps/marketing uses the same layout.

apps/dashboard/
├── app/
│   ├── app.vue
│   ├── pages/
│   │   ├── (auth)/login.vue
│   │   ├── (dashboard)/index.vue
│   │   └── (organizations)/…
│   ├── layouts/
│   ├── plugins/
│   ├── types/
│   └── assets/css/
└── modules/
    ├── shared/          # cross-feature components, composables, and utils
    ├── auth/            # login and session UI
    ├── dashboard/       # task history, queue, approvals
    ├── organizations/   # organization management
    ├── i18n-strip-empty/ # drops untranslated placeholder keys from the bundle
    └── vitehub.ts       # ViteHub KV inside Nuxt's Nitro build

Route groups — (auth), (dashboard), (organizations) — organize pages without affecting URLs. Pages are gated through routeRules with auth: { only: 'user' | 'guest' } and a layout assignment.

Styling and icons

  • UnoCSS with preset-wind4 — utility classes, not Tailwind. The CSS entry is app/assets/css/main.css.
  • @nuxt/icon with the Lucide collection, fully client-bundled (provider: 'none') so no icon request leaves the app.
  • @nuxtjs/color-mode drives theming (dataValue: 'theme').

Server composition

The server/ directory hosts the API transports, webhook ingress, and the Better Auth mount — see API overview and Authentication.

nuxt.config.ts registers vite-hub/nuxt as a module entry, composing the ViteHub KV Runtime Helper into Nuxt's own Nitro build and giving the server a KeyValueStorage backed by fs-lite on the filesystem (.data/kv) when self-hosted, with Cloudflare KV, Deno KV, or Upstash as drop-in driver configuration. Its deployment preset comes from config/env.ts (node unless NITRO_PRESET or VITEHUB_HOSTING names a host), and that preset fixes both the Nitro preset the build emits and the KV driver — see Deployment.

Internationalization

The interface ships English and Italian through @nuxtjs/i18n (strategy: 'no_prefix'), with dictionaries split by scope. See Internationalization.

Auth capability flags

The login page's capabilities (signup enabled, GitHub button) are published via appConfig — captured at build time, deliberately not runtime-overridable. Rebuild after changing auth policy variables. See Authentication overview.

Testing

  • Unit and component tests live in test/unit/ and test/nuxt/.
  • aube run test:browser builds the dashboard, starts the production preview on port 5678, and runs the Playwright suite against the real /api/auth/** endpoints with an in-memory Better Auth adapter (AUTH_E2E_MEMORY=true, set only for that preview server) — the suite creates and signs in its own throwaway account instead of using a live database.
  • Use aube --filter @agent-zero/dashboard run test:browser:ui for Playwright UI mode.
Copyright © 2026