# Frontend Architecture: [Web application name]

> Frontend architecture document for a web application: rendering
> strategy, framework and state management, routing, data fetching and
> caching, component architecture and design system, micro-frontends,
> performance budgets with Core Web Vitals targets, accessibility,
> internationalisation, security, testing, build and deployment,
> observability and browser support. Based on common industry practice,
> Google's Core Web Vitals (LCP, INP and CLS, as published on web.dev,
> checked October 2026) and WCAG 2.2 level AA. Replace every `[bracketed]`
> value and every row marked *Example*; the examples follow a retail web
> shop with a logged-in account area.

<!--
Guidance: How to use this template
- Start from users, devices and networks (section 1.3), not from the
  framework. A rendering strategy that suits office desktops can fail on
  mid-range phones on mobile networks.
- Decide rendering per route, not per application. Marketing pages,
  product pages and account pages usually need different strategies.
- Set performance budgets before building and enforce them in CI.
  Budgets agreed after launch are rarely met.
- Check the current Core Web Vitals set and thresholds on web.dev before
  each revision; Google has replaced metrics before (INP replaced FID in
  March 2024).
-->

## Document control

<!-- Guidance: Record ownership and approval; frontend architecture affects design, product, SEO and security teams. -->

| Field | Value |
|---|---|
| Document ID | [FEA-001] |
| Application | [Name and URL] |
| Version | [0.1] |
| Status | [Draft / In review / Approved / Superseded] |
| Author(s) | [@frontend-architect] |
| Reviewers | [@design-system-lead], [@security], [@accessibility-lead], [@sre] |
| Last updated | YYYY-MM-DD |
| Classification | [Internal] |
| Related | [System design], [Design system docs], [ADRs], [Performance budget dashboard] |

### Approvals

| Role | Name | Decision | Date |
|---|---|---|---|
| Engineering lead | [@name] | [Approved / Changes requested] | YYYY-MM-DD |
| Design lead | [@name] | [Decision] | YYYY-MM-DD |
| Security | [@name] | [Decision] | YYYY-MM-DD |
| Accessibility | [@name] | [Decision] | YYYY-MM-DD |

## Revision history

<!-- Guidance: Note architectural changes, not wording. -->

| Version | Date | Author | Change summary |
|---|---|---|---|
| 0.1 | YYYY-MM-DD | [@name] | First draft |
| 0.2 | YYYY-MM-DD | [@name] | *Example:* Product pages moved from SSR to ISR after cache-hit analysis |
| 1.0 | YYYY-MM-DD | [@name] | *Example:* Approved |

## Contents

<!-- Guidance: Keep aligned with the numbered headings. -->

1. [Introduction](#1-introduction)
2. [Architectural drivers](#2-architectural-drivers)
3. [Rendering strategy](#3-rendering-strategy)
4. [Framework and state management](#4-framework-and-state-management)
5. [Routing](#5-routing)
6. [Data fetching and caching](#6-data-fetching-and-caching)
7. [Component architecture and design system](#7-component-architecture-and-design-system)
8. [Micro-frontends](#8-micro-frontends)
9. [Performance budgets and Core Web Vitals](#9-performance-budgets-and-core-web-vitals)
10. [Accessibility](#10-accessibility)
11. [Internationalisation](#11-internationalisation)
12. [Security](#12-security)
13. [Testing strategy](#13-testing-strategy)
14. [Build and deployment](#14-build-and-deployment)
15. [Observability](#15-observability)
16. [Browser and device support](#16-browser-and-device-support)
17. [Decisions, risks and open questions](#17-decisions-risks-and-open-questions)

## 1. Introduction

<!-- Guidance: Describe what the application does, who uses it, on what devices and networks, and how it fits with the back end. -->

### 1.1 Purpose and scope

This document defines the frontend architecture of [Application]: how
pages are rendered and delivered, how code is organised, and the quality
targets every team building on it must meet. It covers [scope].
*Example:* the public shop (home, category, product, search, cart,
checkout) and the account area; the internal back office is out of scope.

### 1.2 Context

The diagram shows the frontend in its environment.

```mermaid
flowchart LR
    U["Browser"] --> CDN["CDN and edge cache"]
    CDN --> FE["Frontend server (SSR, ISR)"]
    FE --> BFF["Backend for frontend API"]
    U -- "client data requests" --> BFF
    BFF --> SVC["Domain services"]
    FE --> CMS["Headless CMS"]
    U --> RUM["RUM collector"]
```

### 1.3 Users, devices and networks

| Segment | Share of sessions | Typical device | Network | Notes |
|---|---|---|---|---|
| *Example:* Mobile shoppers | 68% | Mid-range Android, 4 GB RAM | 4G, variable | Primary design target |
| *Example:* Desktop shoppers | 27% | Laptop, recent Chrome or Safari | Broadband | Larger baskets |
| *Example:* Tablet | 5% | iPad | Wi-Fi | |
| [Segment] | [%] | [Device] | [Network] | [Notes] |

## 2. Architectural drivers

<!-- Guidance: List the requirements that shape the architecture, with measurable targets and priority. -->

| ID | Driver | Target | Priority |
|---|---|---|---|
| FE-01 | *Example:* Search engine visibility of product and category pages | Full HTML on first response; structured data | Must |
| FE-02 | *Example:* Core Web Vitals "good" for 75% of mobile page loads | See section 9 | Must |
| FE-03 | *Example:* Accessibility | WCAG 2.2 level AA | Must |
| FE-04 | *Example:* Independent releases by 4 product teams | Deploy without cross-team coordination | Should |
| FE-05 | *Example:* 6 languages, 4 currencies | See section 11 | Must |
| FE-06 | *Example:* Price changes visible within 60 s | Cache invalidation | Must |
| [FE-nn] | [Driver] | [Target] | [Priority] |

## 3. Rendering strategy

<!-- Guidance: Compare strategies, then choose per route. Answer for each route: does it need SEO, how personalised is it, how often does content change, and how fast must the first paint be? -->

### 3.1 Options

| Strategy | How it works | Strengths | Weaknesses |
|---|---|---|---|
| CSR (client-side rendering) | Browser downloads JavaScript that renders the page | Simple hosting; rich interactivity | Slow first content on weak devices; weak SEO without extra work |
| SSR (server-side rendering) | Server renders HTML per request, then the client hydrates | Fresh, personalised, crawlable HTML | Server cost per request; time to first byte depends on back end |
| SSG (static generation) | HTML built at build time and served from CDN | Fastest delivery; cheapest | Content stale until rebuild; build time grows with pages |
| ISR (incremental regeneration) | Static pages regenerated after a time or on demand | Near-static speed with freshness | Brief staleness; framework-specific behaviour |
| Streaming SSR | Server sends HTML in chunks as data resolves; slow parts arrive later | Early first paint with dynamic data | More complex error and loading states |

### 3.2 Decision per route

| Route | Strategy | Revalidation | Reason |
|---|---|---|---|
| *Example:* `/` home | ISR | 5 min and on CMS publish | Mostly editorial, high traffic |
| *Example:* `/c/[category]` | ISR | 10 min and on catalogue event | SEO; many pages |
| *Example:* `/p/[product]` | ISR plus client fetch for stock and price | On price or stock event (60 s target) | SEO with fresh commercial data |
| *Example:* `/search` | Streaming SSR | n/a | Query-dependent; results stream after header |
| *Example:* `/cart`, `/checkout` | SSR, no caching | n/a | Personal and transactional |
| *Example:* `/account/*` | CSR inside SSR shell | n/a | Behind login; no SEO |
| [Route] | [Strategy] | [Rule] | [Reason] |

## 4. Framework and state management

<!-- Guidance: Record the framework and why, then classify state. Most state belongs to the server cache or the URL; only a little needs a global client store. -->

| Item | Choice | Rationale |
|---|---|---|
| Framework | *Example:* [React meta-framework] with server components | Supports all strategies in section 3 per route |
| Language | TypeScript, strict mode | Type safety across API contracts |
| Styling | *Example:* Design system tokens plus CSS modules | No runtime CSS-in-JS cost |

| State type | Where it lives | Example |
|---|---|---|
| Server state | Server components or data-fetching cache | Product, prices, orders |
| URL state | Path and query string | Filters, sort, page number |
| Form state | Form library, local to the form | Checkout address |
| UI state | Component state | Open menus, tabs |
| Global client state | *Example:* Small store for cart count and session flags | Cart badge |

Rule: do not copy server data into a global store; read it from the
cache so there is one source of truth.

## 5. Routing

<!-- Guidance: Describe the URL structure, how routes map to code, and rules for redirects, locales and errors. URLs are a public contract. -->

| Topic | Design |
|---|---|
| Route definition | *Example:* File-system routing; one folder per route segment |
| Locale in URL | `/{locale}/...`, for example `/de/p/blue-shirt-1042` |
| Canonical URLs | One canonical per product; `hreflang` alternates per locale |
| Redirects | Managed in a redirect table; permanent redirects for retired URLs |
| Error routes | Custom 404 and 500 pages, server-rendered, under 50 KB |
| Code splitting | Automatic per route; heavy widgets loaded on interaction |
| Prefetching | Links in viewport prefetched on fast connections only |

## 6. Data fetching and caching

<!-- Guidance: Show where data is fetched (server or client), how it is cached at each layer, and how caches are invalidated. Stale prices and stock are business bugs. -->

| Layer | What is cached | Lifetime | Invalidation |
|---|---|---|---|
| CDN | *Example:* ISR HTML, static assets | Assets 1 year (hashed names); HTML per section 3 | Purge by tag on catalogue events |
| Frontend server | Fetch results per request and per tag | 60 s for prices | Tag revalidation from webhook |
| Browser HTTP cache | Static assets | 1 year, `immutable` | New hash per build |
| Client data cache | API responses in the data-fetching library | Stale after 30 s; refetch on focus | Mutation updates cache |

API access: all client calls go to the backend for frontend (BFF), which
shapes responses for screens and keeps tokens server-side. Errors follow
a single problem-details format and map to user-facing messages.

## 7. Component architecture and design system

<!-- Guidance: Describe how UI code is layered and how the design system is consumed and versioned. -->

| Layer | Content | Rules |
|---|---|---|
| Design tokens | Colour, spacing, typography, motion | Only source of visual values |
| Primitives | *Example:* Button, Input, Dialog from the design system package | Accessible by default; no product logic |
| Patterns | Product card, price, address form | Built from primitives; shared across teams |
| Features | Cart drawer, product gallery | Owned by one team; may fetch data |
| Pages | Route components | Compose features; minimal logic |

Design system: [package name and version policy]. *Example:* published
as a versioned package; product teams upgrade within two minor versions;
visual regression tests on every component; components documented with
usage, accessibility notes and do and don't examples.

## 8. Micro-frontends

<!-- Guidance: Use micro-frontends only when team autonomy needs outweigh the performance and consistency cost. If not used, say so and why. -->

Decision: [Used / Not used]. *Example:* Not used for the shop. The four
teams work in one repository with route-level ownership (CODEOWNERS) and
independent feature flags, which meets FE-04 without the duplicated
dependencies and integration cost of runtime composition. Revisit if the
number of teams exceeds eight or if a separately released partner area
is added.

| If used: aspect | Design |
|---|---|
| Composition | [Build-time packages / server-side composition / runtime module federation] |
| Shared dependencies | [Framework singleton policy] |
| Cross-app communication | [URL and custom events only] |
| Consistency | [Shared design system version range] |

## 9. Performance budgets and Core Web Vitals

<!-- Guidance: Use field data at the 75th percentile, separately for mobile and desktop. Set budgets for bytes and requests that keep you inside the vitals targets, and fail the build when they are exceeded. -->

### 9.1 Core Web Vitals targets

Thresholds for "good" as published on web.dev at the time of writing,
measured at the 75th percentile of page loads:

| Metric | Measures | Good | Our target (mobile p75) |
|---|---|---|---|
| LCP (Largest Contentful Paint) | Loading: when the main content is visible | <= 2.5 s | *Example:* <= 2.0 s |
| INP (Interaction to Next Paint) | Responsiveness to user input across the visit | <= 200 ms | *Example:* <= 150 ms |
| CLS (Cumulative Layout Shift) | Visual stability | <= 0.1 | *Example:* <= 0.05 |

Supporting metrics: TTFB (time to first byte) *Example:* <= 0.8 s and
FCP (first contentful paint) *Example:* <= 1.5 s, used for diagnosis.

### 9.2 Resource budgets

| Page type | JS (compressed) | CSS (compressed) | Images above the fold | Requests before LCP |
|---|---|---|---|---|
| *Example:* Product page | 170 KB | 40 KB | 120 KB | 15 |
| *Example:* Category page | 150 KB | 40 KB | 200 KB | 18 |
| *Example:* Checkout | 200 KB | 40 KB | 20 KB | 12 |
| [Page] | [KB] | [KB] | [KB] | [n] |

Budget reasoning: download time for a resource of size $S$ kilobytes on
bandwidth $B$ kilobits per second is

$$
t = \frac{8\,S}{B}
$$

*Example:* 170 KB of JavaScript on a 1.6 Mbit/s connection takes
$t = 8 \times 170 / 1{,}600 = 0.85$ s before parsing and execution, which
is why the JavaScript budget is the tightest constraint on LCP and INP.

Enforcement: [tool and gate]. *Example:* bundle size check and lab
performance run on every pull request; build fails above budget; field
data reviewed weekly.

## 10. Accessibility

<!-- Guidance: State the conformance target, how it is built in, and how it is tested. Automated tools find only part of the issues; plan manual and assistive-technology testing. -->

| Topic | Practice |
|---|---|
| Target | WCAG 2.2 level AA |
| Built in | Accessible design system primitives; semantic HTML first; visible focus; target sizes meet WCAG 2.2 minimums |
| Automated tests | *Example:* axe-core in component and end-to-end tests; zero serious or critical violations allowed |
| Manual tests | Keyboard-only and screen reader (NVDA, VoiceOver) passes on key journeys each release |
| Content | Alt text rules; heading structure; link text guidelines |
| Statement | Public accessibility statement with contact route |

## 11. Internationalisation

<!-- Guidance: Cover languages, formatting, direction, translation workflow and how text expansion is handled in layouts. -->

| Topic | Design |
|---|---|
| Locales | *Example:* en, de, fr, nl, pl, es |
| Message format | ICU message syntax with plurals and placeholders |
| Formatting | `Intl` APIs for numbers, currency, dates |
| Translation workflow | Keys extracted in CI; translation platform; missing keys fail release for Must locales |
| Layout | Allow 40% text expansion; no text in images; right-to-left ready (logical CSS properties) |
| Input | Handle IME composition events in search and forms |

## 12. Security

<!-- Guidance: Cover the browser-side defences: content security policy, output encoding, token handling, third-party scripts and the dependency supply chain. -->

| Topic | Design |
|---|---|
| Content Security Policy | *Example:* Nonce-based `script-src` with `strict-dynamic`; `object-src 'none'`; `frame-ancestors 'none'`; report endpoint |
| XSS prevention | Framework escaping by default; raw HTML only through a sanitiser with an allow-list; lint rule bans unsafe APIs |
| Authentication | Session in `HttpOnly`, `Secure`, `SameSite=Lax` cookies; no tokens in local storage |
| CSRF | SameSite cookies plus CSRF token on state-changing requests |
| Third-party scripts | Allow-list reviewed by security; loaded with integrity where static; none on checkout except payment provider |
| Dependency policy | Lockfile committed; automated vulnerability scanning; new dependencies reviewed for maintenance and licence |
| Other headers | HSTS, `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, `Permissions-Policy` |

## 13. Testing strategy

<!-- Guidance: Define the test layers, their tools, what each must cover and where they run. -->

| Layer | Scope | Tooling | Gate |
|---|---|---|---|
| Unit | Utilities, hooks, formatters | *Example:* Vitest | Every pull request |
| Component | Components with interactions and accessibility | Testing Library, axe-core | Every pull request |
| Visual regression | Design system and key pages | Screenshot comparison | Every pull request |
| Contract | BFF responses match frontend types | Schema tests | Every pull request |
| End-to-end | Search, add to cart, checkout, login | Playwright, 3 browser engines | Before production |
| Performance | Lab vitals and budgets | Lab performance runner | Every pull request |

## 14. Build and deployment

<!-- Guidance: Describe the pipeline from commit to production, environments, release strategy and rollback. -->

| Topic | Design |
|---|---|
| Build | *Example:* Single pipeline; type check, lint, tests, build, budgets |
| Artefact | Container image for the frontend server plus hashed static assets uploaded to CDN |
| Environments | Preview per pull request; staging; production |
| Release | Canary to 5% of traffic for 30 minutes, automatic rollback on error-rate or vitals regression |
| Feature flags | Server-evaluated flags for unfinished features |
| Rollback | Redeploy previous image; static assets of previous build kept for 30 days |

## 15. Observability

<!-- Guidance: Combine real user monitoring (RUM) with server telemetry. Respect privacy: collect only what you need and honour consent. -->

| Signal | Collected | Use |
|---|---|---|
| RUM Core Web Vitals | *Example:* LCP, INP, CLS per route, device class and country, sampled 10% | Field performance tracking against section 9 |
| JavaScript errors | Message, stack (source-mapped), route, release | Error budgets per release |
| Server telemetry | SSR duration, cache hit rate, upstream latency | Diagnose TTFB |
| Business signals | Funnel steps (aggregated) | Detect checkout regressions |

Privacy: [rules]. *Example:* no personal data in RUM payloads; IP
addresses truncated; collection follows the consent settings; data
retained 13 months.

## 16. Browser and device support

<!-- Guidance: Define what "supported" means, which browsers are in each tier, and how the list is reviewed. -->

| Tier | Browsers | Commitment |
|---|---|---|
| Full support | *Example:* Last 2 versions of Chrome, Edge, Firefox, Safari (macOS and iOS); Samsung Internet latest | All features; tested in CI |
| Functional | Older versions with > 0.5% of our traffic | Core journeys work; visual differences accepted |
| Unsupported | Browsers without ES2020 modules | Plain upgrade message; checkout still reachable as HTML form where possible |

Review: browser list updated each quarter from analytics; build targets
generated from the same list.

## 17. Decisions, risks and open questions

<!-- Guidance: Link ADRs and keep risks and open questions current. -->

| ID | Item | Type | Status or mitigation | Owner |
|---|---|---|---|---|
| ADR-021 | *Example:* ISR for product pages with client-side price and stock | Decision | Accepted | [@name] |
| ADR-022 | *Example:* No micro-frontends for the shop | Decision | Accepted | [@name] |
| R-01 | *Example:* Third-party tag growth breaks the JavaScript budget | Risk | Tag governance and budget gate | [@name] |
| OQ-01 | *Example:* Should search use edge rendering in the next phase? | Question | Prototype in Q2 | [@name] |
| [ID] | [Item] | [Decision / Risk / Question] | [Status] | [@name] |

## Standard and licence note

Based on common industry practice for frontend architecture. Core Web
Vitals metrics and "good" thresholds are as published by Google on
web.dev (LCP, INP and CLS; checked October 2026), and accessibility
targets refer to W3C WCAG 2.2 level AA; verify both before each
revision. Original text written for this collection; examples are
illustrative. Template licence: MIT.
