sidebar-order
"Schema slot order must match the order the page renders them in."
Venue: check — Schema slot order must match the order the page renders them in.
The editor renders one sidebar card per group (and one per ungrouped slot), in the order the schema declares them. This check server-renders the section’s baseline fixture, reads the first-appearance order of the slot markers in the resulting HTML, and asserts that it matches the schema’s declaration order.
Three carve-outs, each of which looks like a bug if you don’t know about it:
- A slot rendered more than once counts at its first marker. An address shown in a header and again in a footer is ordered by the header.
- Order within a group is not checked, and neither is contiguity. A group’s members may appear in any order on the page, and other slots may sit between them. Responsive layouts legitimately do both, and the sidebar collapses the group into one card anyway.
- A slot declared but never rendered is excluded. It has no position on the page, so it cannot contradict one.
Reason
Section titled “Reason”Two files describe the same section in two different orders, and only one of them is visible to the person editing. The failure mode is drift: you reorder the markup — move the eyebrow above the headline, promote the price — the schema keeps its original order, and the sidebar quietly stops matching the page.
Nothing breaks. The section renders, the slots fill, and every card still works. The user just finds that the second card edits the first thing they see, and stops trusting the panel. This check makes that drift impossible to ship rather than merely unlikely.
Reorder the schema, not the page. The page’s visual order is the truth — it is what the
user is looking at — so bring the schema to it: reorder the slots keys so declaration
order matches the page’s top-to-bottom order. That is the whole fix even when you have
group cards — a card sits where its first member is declared, and the order you wrote the
layout array in decides nothing.
Before
Section titled “Before”The schema declares headline first, the page renders eyebrow first:
// sections/hero/section.ts — template-kit/sidebar-orderimport { defineSchema, type SectionProps, text } from "@homepages/template-kit";
export const schema = defineSchema({ label: "Hero", slots: { headline: text.medium({ label: "Headline" }), eyebrow: text.short({ label: "Eyebrow" }), price: text.short({ label: "Price" }), },});
export type Props = SectionProps<typeof schema>;// sections/hero/Renderer.tsx — the page, top to bottom: eyebrow, headline, priceimport { bindSlots, Section, Slot } from "@homepages/template-kit";
import { schema } from "./section.js";import type { Props } from "./section.js";
export function Renderer({ slots }: Props) { const slot = bindSlots(schema, slots);
return ( <Section> <Slot.Text slot={slot.eyebrow} as="p" /> <Slot.Text slot={slot.headline} as="h1" /> <Slot.Text slot={slot.price} as="p" /> </Section> );}The Renderer is untouched. The schema moves:
import { defineSchema, type SectionProps, text } from "@homepages/template-kit";
export const schema = defineSchema({ label: "Hero", slots: { eyebrow: text.short({ label: "Eyebrow" }), headline: text.medium({ label: "Headline" }), price: text.short({ label: "Price" }), },});
export type Props = SectionProps<typeof schema>;See also
Section titled “See also”- Arranging the editor sidebar with
layout— whatlayoutgroups, and why slot declaration order is what sequences the cards. missing-slot-marker— the markers this check reads to establish the page’s order.