Skip to content
HomePagesHomePages template kit

Organize a section's files

Structure a section's files beyond the reserved contract files.

Structure a section beyond its contract files.

Starting from a section that renders, add a components/ folder and pull a piece of markup out into its own module.

// sections/<name>/components/Callout.tsx
import type { ReactNode } from "react";
export function Callout({ label, value }: { label: string; value: string }): ReactNode {
return (
<div className="rounded-lg border border-ink/10 p-4">
<div className="text-sm text-ink/60">{label}</div>
<div className="text-lg font-semibold text-ink">{value}</div>
</div>
);
}

Import it into Renderer.tsximport { Callout } from "./components/Callout";, beside the imports the scaffolded file already carries — then render it:

Renderer.tsx
<Callout label="Status" value="For sale" />

Three names are reserved, and only at the section folder’s root: Renderer.tsx, section.ts and fixtures.ts — the three files every section folder holds, and the only three anything loading the section looks for. section.ts declares the schema, each slot carrying its own fill:; fixtures.ts exports the sample content; Renderer.tsx default-exports the markup (Sections and declarations).

Everything else in the folder is yours — components/, hooks/, utils/, stylesheets, any nesting, any number of support modules, and "use client" islands. A binary asset (an image, a font, an archive) may live under an assets/ folder too, but only if something in the section references it — see bundle-binary-asset for the rule and what an unreferenced one costs you.

Nesting is free below the root, and only below it: a reserved name has to sit directly in the section folder. Moving fixtures.ts into a fixtures/ folder, or section.ts under declarations/, leaves the section with a file check cannot find — which is what bundle-incomplete reports.

Every file under templates/<template>/ — not only the reserved ones — feeds pack’s content hash of the template tree, stamped into pack-manifest.json. Editing a component, a util, or even a comment inside a section folder changes that hash on the next pack, exactly as editing Renderer.tsx would.

The component file under Steps, its import in Renderer.tsx, and the one line there that renders it are the whole change.

Verify with the author loop.

  • bundle-incomplete — a reserved contract file moves out of the section folder’s root while you are reorganizing around it.
  • Add a second template — where a section folder carrying the three reserved files this page organizes around comes from.
  • Islands — a "use client" file is one more kind of file the section folder is free to hold.
  • template-kit pack — what produces the content hash and what it refuses to pack.
  • bundle-binary-asset — when a binary file in the folder must be referenced, and what happens if it isn’t.