Frontend Experience
The Cirrus CDN frontend is a Next.js 15 application (frontend/) that delivers an operator-focused SPA backed by the same REST APIs documented in Chapter 3. This chapter outlines the application structure, data-fetching strategy, and UX patterns that ensure parity between portal actions and API capabilities.
Technology Stack
- Framework: Next.js App Router (React Server Components + Client Components).
- Language: TypeScript, bundled with pnpm.
- UI Toolkit: Shadcn-based components located under
frontend/components/ui. - State: Client components manage local state with React hooks; cross-component state is minimal and persisted via
localStorage. - Build Output: Static export (
pnpm build), deployed as part of the FastAPI container (/app/static).
Directory Layout
| Path | Purpose |
|---|---|
frontend/app/ | Route definitions (e.g., /login, /sites, /users, /settings, /tokens). |
frontend/components/ | Reusable UI primitives (tables, dialogs) and feature modules (sites/, users/). |
frontend/hooks/ | Custom hooks (use-toast, etc.). |
frontend/lib/api.ts | Typed API client referencing backend endpoints. |
frontend/styles/ | Tailwind and global styling. |
Routes leverage client components where interactivity is required (e.g., login form, domain management).
Authentication Workflow
frontend/app/login/page.tsxhandles credential submission:- Calls
api.loginwith username/password. - On success, stores
isAuthenticatedand user details inlocalStorage. - Navigates to
/sites. - Displays toast notifications for success/failure.
- Calls
api.logoutclears the session cookie; frontend also clearslocalStorage.api.mefetches current user metadata to populate UI (e.g., navigation header).
Sites Management
frontend/app/sites/page.tsx and components/sites/ provide domain CRUD and insight tooling:
SitesOverviewlists domains, caching status, origin counts, and certificate availability (placeholder badges until certificate metadata is exposed directly).AddSiteDialogwraps thecreateDomainAPI call, re-fetching domain lists on completion.AccessViewfetches/domains/{domain}/cnameto show assigned nodes and TTLs.OriginManagement,RuleManagement,HeaderManagement,CertificateManagement, andDeleteSitecomponents wrap respective API endpoints for targeted updates.- Tabs are controlled via query parameters (
domain,tab), allowing deep links to specific management workflows.
Users & Tokens
UserManagement(undercomponents/users/) handles listing, creation, update, and deletion of operator accounts, mirroring/api/v1/users.- Service token UI (under
app/tokens/) requires the user to supply the master token; the API client attaches it as aBearerheader.
Settings & Miscellaneous Pages
app/settingssurfaces session management (change password), purge actions, and ACME controls.app/usersandapp/tokensrely on shared UI components to enforce consistent patterns (tables, dialogs, confirmation modals).
API Client Abstraction
frontend/lib/api.ts centralizes HTTP calls:
- Automatically sets
Content-Type: application/json(unlessFormData/binary body). - Includes credentials for session-backed APIs.
- Throws
Errorwith meaningful message based on HTTP response content (detailfield if present). - Exposes typed interfaces for domain configs (
DomainConf), user metadata, cache rules, ACME status, etc. - Supports master token usage by attaching
Authorizationheaders when provided.
This abstraction ensures UI components stay declarative and tests (where applicable) can stub API methods directly.
State Persistence & UX Notes
- Light use of
localStoragecaches the logged-in user to personalize the UI. Sensitive data (tokens) is not stored persistently beyond the session. - Toast notifications provide immediate feedback for asynchronous operations.
- Components rely on React hooks (
useEffect,useState) for data fetching; no global store is required given the page-scoped nature of workflows. - Navigation uses Next.js router to update query params without full reloads, preserving SPA responsiveness.
Build & Deployment
pnpm buildperforms a static export (outdirectory). TheDockerfilecopies this export into/app/static, allowing FastAPI to serve the SPA alongside APIs.- Runtime configuration (e.g., API base URL) is set via
NEXT_PUBLIC_API_BASE. In Docker, the frontend uses relative paths by default. pnpm lintenforces TypeScript and ESLint rules;pnpm devruns the dev server for local iteration.
The frontend mirrors backend capabilities and uses the same data contracts, ensuring a consistent operator experience whether actions are performed manually or via automation. Chapter 8 examines the security controls that safeguard both API and UI layers.