Skip to main content

Fleet Studio v2 Architecture

System Overview​

Every route under src/app/ is a static server component that exports its own metadata and renders hardcoded JSX matching the legacy HTML site's markup. There is no client-side state, no CMS, and no backend - content changes mean editing the page file directly.

Architecture Diagram​

graph TB
subgraph Legacy["Legacy: fleet-studio-site-html"]
LegacyPages["Static HTML pages + CSS"]
end
subgraph FE["fleetstudio-v2 (Next.js)"]
RootLayout["app/layout.js<br/>force-static, legacy CSS imports"]
Pages["app/{about,contact,services/*,work/*,insights/*}"]
ServiceCard["components: ServiceCard<br/>(extracted, reused)"]
Sitemap["app/sitemap.js"]
Robots["app/robots.js"]
end
Docker["Dockerfile"]

LegacyPages -.->|"markup/classes replicated"| Pages
RootLayout --> Pages
Pages -->|"uses"| ServiceCard
Sitemap -->|"reads"| Pages
Docker -->|"containerizes"| FE

How to read this diagram​

Arrows mean flow / dependency / "talks to", not button clicks. The dotted line means "source of truth for content/markup," not a runtime dependency.

Core Components​

Page routes (src/app/**/page.js)​

Each route is a server component exporting metadata for SEO and rendering hardcoded JSX. Services, Work, and Insights are further split into per-topic subpages (e.g. services/ai-consulting, work/healthcare, insights/ai-maturity-gap).

sitemap.js / robots.js​

App Router special files generating sitemap.xml and robots.txt dynamically from NEXT_PUBLIC_SITE_URL, replacing static files the legacy HTML site shipped.

ServiceCard component​

The one componentized piece of UI, extracted from duplicated markup across the Services pages - everything else stays hardcoded per AGENTS.md's "no component extraction" rule.

Data Flow​

There isn't one in the traditional sense - this is a static site. The only "flow" is build-time: page files are compiled and pre-rendered, and sitemap.js/robots.js are evaluated at request/build time to reflect the current route list.

Design Decisions​

Hardcode pages instead of componentizing​

Context: The legacy site's markup and class names are tightly coupled to its CSS; abstracting into shared components risks class-name drift breaking styles.

Decision: AGENTS.md mandates hardcoding JSX per page and matching legacy class names exactly, with ServiceCard as a deliberate, narrow exception.

JavaScript only, no client components on pages​

Context: The site needs to stay statically rendered for SEO and simplicity; adding TypeScript or client-side interactivity would pull the project away from a 1:1 static replica.

Decision: Pages remain server components (no "use client"), no TypeScript, no dynamic state - documented explicitly in AGENTS.md so future changes don't silently drift the architecture.

Technology Stack​

LayerTechnology
FrameworkNext.js App Router (force-static)
LanguageJavaScript
StylingTailwind + imported legacy CSS
DeployDocker
Default branchmain

Next Steps​