Skip to main content

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

PathPurpose
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.tsTyped 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.tsx handles credential submission:
    • Calls api.login with username/password.
    • On success, stores isAuthenticated and user details in localStorage.
    • Navigates to /sites.
    • Displays toast notifications for success/failure.
  • api.logout clears the session cookie; frontend also clears localStorage.
  • api.me fetches 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:

  • SitesOverview lists domains, caching status, origin counts, and certificate availability (placeholder badges until certificate metadata is exposed directly).
  • AddSiteDialog wraps the createDomain API call, re-fetching domain lists on completion.
  • AccessView fetches /domains/{domain}/cname to show assigned nodes and TTLs.
  • OriginManagement, RuleManagement, HeaderManagement, CertificateManagement, and DeleteSite components 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 (under components/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 a Bearer header.

Settings & Miscellaneous Pages

  • app/settings surfaces session management (change password), purge actions, and ACME controls.
  • app/users and app/tokens rely 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 (unless FormData/binary body).
  • Includes credentials for session-backed APIs.
  • Throws Error with meaningful message based on HTTP response content (detail field if present).
  • Exposes typed interfaces for domain configs (DomainConf), user metadata, cache rules, ACME status, etc.
  • Supports master token usage by attaching Authorization headers 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 localStorage caches 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 build performs a static export (out directory). The Dockerfile copies 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 lint enforces TypeScript and ESLint rules; pnpm dev runs 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.