The marker contract
Why a section's rendered DOM carries attributes naming the declarations behind it, and what that contract does and does not ask of your markup.
What it is
Section titled “What it is”A section’s rendered DOM carries attributes that name which declaration produced each piece of it — enough for something outside your renderer to point at an element and know which schema key put it there. The whole contract fits in one sentence: to render slot X, you use slot X’s primitive — there is nothing else, and the marker cannot be anywhere else. The attribute names themselves are in the reference; this page is about why they exist and what they do, and do not, obligate you to do.
Why it works this way
Section titled “Why it works this way”The pipeline establishes that your code runs at exactly two moments, and that in both of them the platform hosting your renderer never sees your component — only the DOM it produced.
That is the constraint the editor lives inside. When someone clicks a piece of content on the canvas, the editor has to resolve that click back to the schema key that produced it — but it has never had your component to inspect, only the markup your renderer emitted, and that markup is the only thing the two sides of that boundary share. So the identity of a piece of content has to travel in the DOM itself, as an attribute on the element carrying it, because there is nowhere else for it to live.
The design choice that follows is where the markers sit: on your own elements, not on a
wrapper the kit inserts around them. A slot’s binding carries its identity, and its
primitive derives the marker from it and places it on the element the primitive renders —
the element you named via as, with that element’s own props. Because the marker rides
on an element you already wrote rather than one the kit owns, the kit never needs a layout
layer of its own, and your DOM stays exactly the DOM you wrote.
The primitive is the marker, and that identity is deliberately exclusive: there is no
marker-only carrier, no bag of attributes to spread onto an element of your own, and no
second route identity could arrive by. When a primitive seems not to fit the markup you
need, the answer is that the primitive can be that markup — as accepts any element,
the remaining props are that element’s own, and your children render inside — never that
you attach the marker some other way. One primitive per slot means the editor’s picture
of the page and your markup cannot disagree.
The same design is why a slot can be marked in several places at once: each rendered copy
of a slot’s value carries its own marker, is patched live, and is its own editing target —
a headline printed twice is editable in both spots, not only the first. A copy that should
never resolve a click — a carousel clone, a decorative mirror — declines selection with
a render-time lever (selectable={false});
it keeps its identity and keeps receiving patches, because a copy without identity would
visibly lag its siblings.
How it works
Section titled “How it works”The direction of travel matters. Every marker but one is emitted for you — the primitives that render a slot read its own schema and put the right attribute on the right element, so you never author a marker’s name yourself. One attribute goes the other way: it names the deliverable’s own instance, and it is written by the platform onto the section root, not by anything in your renderer. The full set, and which is which, is on the reference page.
What it is not
Section titled “What it is not”Markup is yours
Section titled “Markup is yours”Nothing about the slot primitives dictates your DOM beyond the one element each one
renders. There is no wrapper you didn’t ask for, no forced tag, no required container, and
no ordering constraint beyond what sidebar-order asks of the
markers themselves. Layout, headings, links, icons, cards, tables — all plain JSX around
them.
Markers are not styling hooks
Section titled “Markers are not styling hooks”A marker names the element carrying a slot’s value, and which element that is depends on what the slot declares — an image slot’s marker can land on a framed wrapper, on the image itself, or on a generated picture element, depending entirely on the schema. A CSS selector written against a marker attribute is written against that choice, and a schema change moves it out from under the selector without touching a line of your renderer. Style your own classes, and leave the markers to the editor.
Markers are not attributes to write by hand
Section titled “Markers are not attributes to write by hand”Every marker other than the platform’s own is emitted for you; writing one in your JSX by
hand does not create a slot, because a slot exists only where the schema declares it. Both
halves of that are checked: no-slot-marker-literal
rejects any hand-written data-slot-* in section code, and
missing-slot-marker reports a declared slot that never
reached the DOM.
Where next
Section titled “Where next”- Slot primitives — the full set
of marker attributes, and the primitive that emits each one; whatever element your
markup needs, the primitive can be it via
as. missing-slot-marker— the check that proves each editable slot reached the rendered page.sidebar-order— the one ordering constraint the markers themselves carry.- Server and client — why the renderer that emits these markers ships no JavaScript, and where browser-side code goes instead.