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
nullfor 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 Builderon the server. - Template Simplicity: Templates should simply render the strings provided in
ViewDatawithout 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.