Slots return the decision about content to the consumer
Aliases: named slot · content projection · children slot
What it is
A content slot is a hole in a component’s own structure: the shell, spacing, overflow, and focus ring belong to the component; what occupies the hole belongs to the consumer. The consumer places a title, an action, media, or an arbitrary subtree into that position, instead of crushing content into strings and booleans the component must interpret. Returning the decision means “what this patch of UI says” leaves the component’s interface and returns to the markup at the call site.
It is not “one more prop named extra”. A prop is still interpreted by the component author; nodes in a slot are interpreted by the consumer. A card’s title slot can be a line of text or a title group with a badge; the component need not know those shapes in advance.
Why it happens
Once a component takes content into its own property table, the author is forced to enumerate shapes: how long the title is, whether a button sits on the right, what the empty state draws. Enumeration cannot keep up with the product, so properties inflate and every new semantic becomes a switch. A slot deletes shape from the interface: the component declares only geometric and behavioural constraints on the hole (max height, scrollability, participation in focus order), and content arrives at runtime as a subtree.
The split holds because layout constraints and content semantics are not the same decision. A shell knows it is a 48-pixel header; it does not know whether today’s header holds a search field or a segmented control. Encoding the latter as properties forces the shell author to act as the page author. Handing the former to the consumer lets every call site invent its own spacing. The slot cuts the two apart: constraints stay in the component, semantics stay at the call site.
Where it stops holding
When the content shape is closed and must not be customised, a slot is a burden — the “selected” state of a switch or a tab must not become a hole that accepts arbitrary nodes; that would break the component’s own state machine. For controls whose accessible name and role must be synthesised by the component, holes may open only where they cannot overwrite that name. Server-rendered surfaces fed from structured fields, with no markup tree to insert into, have nowhere for a slot to attach. Choosing an appearance preset is a different problem; extra content holes will not solve it.
Applying it
- Turn regions the consumer always edits into named slots (title, actions, media). Keep regions the consumer must never edit as internal implementation.
- Write geometric and behavioural constraints per slot: min/max size, overflow, whether the shell collapses when empty — do not silently allow unbounded growth.
- Do not replace named slots with a junk-drawer prop called
extraorcontent; content with no named position cannot be placed. - How to check: take three real call sites and see whether they simulate, with switches, a structure that belongs in a slot. Every such switch is a content decision that should have been a hole. Then fill the slot with extreme length and with nothing: the shell constraints must still hold, and page meaning must still be decided at the call site.
Related
- Same group: R1.11.2 Assembly is less ambiguous than passing props · R1.11.3 Legal parent-child pairings need explicit constraints · R1.11.4 Context lets children adapt to the container they sit in
- Adjacent: R1.02 Component library and variants · R1.08 Premature abstraction
- Search terms:
content slot·named slot·content projection