Sections and declarations
A section is one folder — your React plus three declarations the platform reads — spread across three files, one per declaration.
What it is
Section titled “What it is”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 |
Why it works this way
Section titled “Why it works this way”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.
How it works
Section titled “How it works”One authoring form, three files
Section titled “One authoring form, three files”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.tssection.tsexportsschemaas a named export (plusProps, derived fromschema). It sits in the published import graph:Renderer.tsximportsschemafrom it as a value.fixtures.tsimports{ schema }from./sectionand exports a namedfixtures. Nothing in the published import graph importsfixtures.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.
What it is not
Section titled “What it is not”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.
Where next
Section titled “Where next”- 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.