Skip to content

Components

A component is a named DOM subtree, identified by one or more CSS selectors. Names replace the generic accessibility role in enriched snapshots, so an agent reading the page sees DepartureDatePicker instead of group.

- name: DepartureDatePicker
selector: '[data-picker="departure"]'
source: src/components/DatePicker.tsx
children:
- name: date-input
selector: input
- name: day
selector: '[role="gridcell"]'

name and selector are required. See Schema reference for the full field list, including description, source, and memory.

selector accepts a single CSS selector string or an array of strings:

# Single selector
- name: SubmitButton
selector: 'button[type="submit"]'
# Array — alternates tried in order, first match wins
- name: SearchInput
selector:
- '[data-component="SearchInput"]'
- 'input[type="search"]'
- '#search'

Use the array form when you want a stable name across multiple variants of the UI — a redesigned page, a feature flag, or a third-party widget you don’t control. The array isn’t an OR over all matches; the runtime takes the first selector that matches anything and stops.

If a selector matches multiple elements, all matches get the name. Selectors are not required to be unique.

The recommended pattern is to render a data-component="<Name>" attribute on the root element of each named component, then select on that attribute:

<nav data-component="Navigation"></nav>
- name: Navigation
selector: 'nav[data-component="Navigation"]'

This decouples the sightmap from class names, CSS modules, and styling refactors. It costs one attribute per named component and is trivial to grep for.

It is a convention, not a requirement. Any CSS selector works.

Selectors inside children are evaluated within their parent’s matched subtree, not against the whole document. This is how the spec avoids naming collisions between, say, two card components that each contain a button.primary.

- name: SearchCard
selector: '[data-component="SearchCard"]'
children:
- name: submit
selector: 'button.primary' # only inside SearchCard's subtree
- name: BookingCard
selector: '[data-component="BookingCard"]'
children:
- name: submit
selector: 'button.primary' # only inside BookingCard's subtree

Components at the file root are global — matched on every view. Nested inside a view, they are scoped to that view. Both forms are additive: a view sees its own components plus all globals. See Views for the full rule.

Requests for API endpoints. Memory for the freeform notes you can attach to any component.