Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Frontend Architecture

Aero2's frontend is a single-page application (SPA) built with React 19 and Vite, served by the Cloudflare Worker.

Tech Stack

TechnologyPurpose
React 19UI framework
ViteBuild tool and dev server
React RouterClient-side routing
CSS ModulesComponent styling
React ContextState management (AuthContext)

Phase 1 Approach: Single SPA with Context-Based Routing

In the current architecture, a single build serves both the developer dashboard and per-app auth pages. The Worker passes an appContext object to the SPA that determines which layout and routes to render.

App Context

The Worker injects the app context into the HTML page:

// appContext passed from Worker to SPA
interface AppContext {
  mode: "dashboard" | "app";
  app: {
    slug: string;
    name: string;
    branding: {
      logo_url?: string;
      favicon_url?: string;
      primary_color?: string;
    };
  };
}
  • mode: "dashboard" -- The current hostname is the dashboard subdomain. Render the full developer console with sidebar navigation, app management, team settings, etc.
  • mode: "app" -- The current hostname is an application subdomain. Render branded auth pages (login, signup, MFA) using the app's branding configuration.

Dashboard Layout

When mode === "dashboard", the SPA renders the developer console:

  • Sidebar navigation: Apps, Team, Account
  • App list page: Cards showing name, slug, user count, creation date
  • App management pages:
    • Overview (user count, login activity, quick links)
    • Users (browse/search, view profiles, disable/enable)
    • Auth Methods (toggle email/password, social providers, MFA policy)
    • Identity Providers (add/edit/remove IdPs)
    • Branding (logo upload, color picker, login page preview)
    • API Keys (list, create, revoke, rotate)
    • Roles and Permissions (configure role system)
    • Organizations (view orgs and members)
    • Audit Logs (app-scoped event log)
    • Settings (signup mode, session TTL, domain restrictions)
  • Team management: Invite members, manage roles, transfer app ownership
  • Account: Developer profile, change password, MFA setup

Dashboard Routes

dashboard.aero2.dev/
  /login                        -> Developer sign-in
  /signup                       -> Developer sign-up
  /                             -> Application list (after login)
  /teams                        -> Developer Team management
  /apps/:slug/overview          -> App overview
  /apps/:slug/users             -> App user management
  /apps/:slug/auth              -> Auth method configuration
  /apps/:slug/idps              -> Identity provider management
  /apps/:slug/branding          -> Login page customization
  /apps/:slug/api-keys          -> API key management
  /apps/:slug/roles             -> Roles and permissions
  /apps/:slug/organizations     -> Organization management
  /apps/:slug/logs              -> Audit logs
  /apps/:slug/settings          -> App settings
  /account                      -> Developer profile
  /account/team                 -> Team members

App Layout

When mode === "app", the SPA renders branded auth pages for end users:

  • Login form (email/password + social IdP buttons)
  • Signup form with email verification
  • MFA verification page
  • Password reset flow
  • OAuth2 authorization consent

Per-App Routes

swift-maple.aero2.dev/
  /login                        -> End-user sign-in (branded)
  /signup                       -> End-user sign-up
  /mfa                          -> MFA verification
  /forgot-password              -> Password reset
  /oauth2/authorize             -> OAuth2 authorization endpoint
  /oauth2/token                 -> Token endpoint
  /oauth2/userinfo              -> UserInfo endpoint
  /oauth2/jwks.json             -> JWKS endpoint
  /.well-known/openid-config..  -> OIDC discovery
  /api/users/me                 -> Current user profile
  /api/sessions                 -> Session management
  /api/organizations            -> Org management (if enabled)

Component Library

Reusable UI components live in src/frontend/components/ui/:

  • Button -- Primary, secondary, danger, ghost variants with loading state
  • Card -- Container with header, body, footer sections
  • Input -- Text, email, password inputs with validation states
  • Modal -- Dialog overlay with confirm/cancel actions
  • Spinner -- Loading indicator
  • Toast -- Notification system (success, error, warning, info)
  • Table -- Data table with sorting and pagination
  • Badge -- Status indicator labels
  • Dropdown -- Menu and select dropdowns

State Management

State is managed through React Context:

  • AuthContext -- Provides user, isAuthenticated, isLoading, signOut(), and session information to all components
  • No external state management library (Redux, Zustand, etc.) -- React Context is sufficient for the current scope

Routing

React Router handles client-side navigation. The Worker serves the SPA HTML for all non-API routes, and React Router matches the path client-side.

Phase 2 (Future): Split Builds

A planned future optimization is to produce two separate builds:

  • dist/dashboard/ -- Full developer console bundle (larger, feature-rich)
  • dist/auth/ -- Lightweight auth page bundle (smaller, loads branding dynamically)

The Worker would serve the appropriate bundle based on subdomain. The auth bundle would be significantly smaller since it only needs login, signup, and MFA components.