Skip to content
HomePagesHomePages template kit

Sections and declarations

A section is one folder — your React plus three declarations the platform reads — spread across three files, one per declaration.

A section is one folder: your React, plus three declarations the platform reads.

Declaration Declares File Reference
schema The slots the section has, and how AI fills each one section.ts The schema · The fill declaration
fixtures Sample content for local preview fixtures.ts fixtures.ts
Renderer.tsx The markup Renderer.tsx Renderer.tsx

The declarations sit outside Renderer.tsx because the platform reads them without your component: schema types the renderer’s props, states what is editable at all, and carries on each slot the decision the fill step reads to give that slot a value; fixtures are what a local preview renders against. Those files are read outside a browser, which is why none of them may carry the "use client" directive — see no-client-directive-in-contract.

Everything a section renders from — the schema, the fill spec, the renderer’s types — comes from one specifier, @homepages/template-kit, on purpose: whichever of the three files you’re reading, there is exactly one place to look for what the platform provides. The lone exception is @homepages/template-kit/fixtures, which fixtures.ts imports the golden scenarios from — the same instinct as the paragraph above, applied to imports rather than directives: dev-only sample data is kept off the root barrel so it can never reach a published renderer’s import graph.

The three declarations spread across three files, keyed to what reaches a published bundle and what stays dev-only:

sections/hero/
Renderer.tsx
section.ts
fixtures.ts
  • section.ts exports schema as a named export (plus Props, derived from schema). It sits in the published import graph: Renderer.tsx imports schema from it as a value.
  • fixtures.ts imports { schema } from ./section and exports a named fixtures. Nothing in the published import graph imports fixtures.ts — that is what keeps the dev-only golden corpus out of a published bundle, structurally, with no author discipline required.

This is the only legal shape; check rejects a folder missing any of the three files. Copying a section folder is how you get all three.

The declarations are not values the renderer reads at runtime. schema reaches Renderer.tsx as a type, not a value — its props type is derived from the schema instead of hand-written, so slot values arrive already resolved on the props object. Your component never has to look a slot up in the schema; props-from-schema is the rule that enforces the derivation.

Fixtures are not content. They are dev-only sample data for local preview, which is why the golden scenarios sit on their own entry point instead of the package root: a renderer cannot pick up preview data through the one specifier it already imports from, and a published artifact has no business carrying any. Import them from the fixtures declaration, never from Renderer.tsx.

  • The schema — declaring slots.
  • The fill spec — the decisions that fill them.
  • fixtures.ts — the sample content a preview renders.
  • Renderer.tsx — the props your markup receives.
  • Organize a section’s files — structuring the rest of the folder, beyond the reserved contract files.
  • Slots — the one thing every schema declares.
  • The pipeline — where fill and render sit relative to your code, and why the declarations are read without your component.