Files
gridpilot.gg/docs/architecture/website/VIEW_DATA.md
2026-01-18 23:55:26 +01:00

2.4 KiB

ViewData (Website Templates)

ViewData is the only allowed input type for Templates in apps/website.

Authoritative contract: WEBSITE_CONTRACT.md.

1) Definition

ViewData is a JSON-serializable, template-ready data structure:

  • primitives (strings/numbers/booleans)
  • arrays and plain objects
  • null for missing values

2) What ViewData is NOT

ViewData is not:

  • an API Transport DTO (raw transport)
  • a ViewModel (client-only class)
  • a Display Object instance

3) Construction rules

ViewData is created by ViewData Builders:

Server Components (RSC)

const apiDto = await PageQuery.execute();
const viewData = ViewDataBuilder.build(apiDto);
return <Template viewData={viewData} />;

Client Components

'use client';

const [viewModel, setViewModel] = useState<ViewModel | null>(null);

useEffect(() => {
  const apiDto = await apiClient.get();
  const vm = ViewModelBuilder.build(apiDto);
  setViewModel(vm);
}, []);

// Template receives ViewData from ViewModel
return viewModel ? <Template viewData={viewModel.viewData} /> : null;

Templates MUST NOT compute derived values.

ViewData Builders MUST NOT call the API.

4) Formatting and SEO

ViewData is responsible for providing fully formatted strings to Templates for Server-Side Rendering (SSR).

  • SEO Requirement: All data required for search engines (prices, dates, counts, labels) MUST be formatted in the ViewData Builder on the server.
  • Template Simplicity: Templates should simply render the strings provided in ViewData without further processing.

5) Determinism rules

Any formatting used to produce ViewData MUST be deterministic.

Forbidden anywhere in formatting code paths:

  • Intl.*
  • Date.toLocaleString() / Date.toLocaleDateString() / Date.toLocaleTimeString()

Reason: SSR and browser outputs can differ.

Localization MUST NOT depend on runtime locale APIs. If localized strings are required, they MUST be provided as deterministic inputs (for example via API-provided labels or a deterministic code-to-label map) and passed through ViewData Builders into ViewData.

5) Relationship to Display Objects

Display Objects are used to implement formatting/mapping, but their instances MUST NOT be stored inside ViewData.

Only primitive outputs produced by Display Objects may appear in ViewData.