Skip to content

Page Definition

A page definition binds a page type to a route, an optional entity, and optional slot bindings. Pages are declared in spec.pages of the Cell manifest.

Fields

FieldTypeRequiredDescription
keystringYesUnique page identifier within the manifest
typePageTypeYesPage type (see below)
titlestringYesDisplay title shown in the page header
pathstringYesRoute path, must start with /
entitystringNoEntity key — required for entity-bound page types
menuobjectNoNavigation menu configuration
optionsobjectNoArbitrary key/value options passed to the page renderer
dataContextDataContextDefinitionNoData binding context
dataProvidersDataProviderDefinition[]NoAdditional data providers
slotBindingsSlotBinding[]NoPrimitives to inject into named zones on this page
primitivestringNoCustom page only: registered primitive key to render as the page body

Page types

TypeEntity requiredSlot zones
entity-listYesheader, toolbar, table, footer
entity-detailYesheader, navigation, content, footer
entity-createYesnone
entity-editYesnone
dashboardNoheader, content, footer
customNocontent

SlotBinding

FieldTypeRequiredDescription
slotstringYesZone binding point: zone, zone.before, or zone.after
primitivestringYesRegistered primitive key
versionstringNoSemver to pin the primitive version
propsobjectNoStatic props to pass to the primitive
modestringNoOverride the inferred mode: replace, prepend, or append

When mode is not set, the mode is inferred from the slot value: .before suffix means prepend, .after suffix means append, no suffix means replace.

Semantic rules

  • Page keys must be unique across the manifest.
  • Page paths must be unique and start with /.
  • Entity-bound pages (entity-list, entity-detail, entity-create, entity-edit) require entity.
  • Non-entity pages (dashboard, custom) must not have entity.
  • primitive is only meaningful on type: custom pages.
  • Multiple slotBindings targeting the same zone as replace are resolved last-wins.
  • Multiple prepend or append bindings at the same zone stack in declaration order.

Examples

Minimal entity list page:

yaml
- key: products-list
  type: entity-list
  title: Products
  path: /products
  entity: product

Entity list page with slot bindings:

yaml
- key: products-list
  type: entity-list
  title: Products
  path: /products
  entity: product
  slotBindings:
    - slot: toolbar.before
      primitive: beta-banner
      props:
        message: "Beta feature"
    - slot: table.after
      primitive: export-button
    - slot: footer
      primitive: custom-pagination

Custom page rendered by a registered primitive:

yaml
- key: reports
  type: custom
  title: Reports
  path: /reports
  primitive: blank-slot
  slotBindings:
    - slot: content
      primitive: reports-dashboard

Dashboard page with a header banner:

yaml
- key: dashboard
  type: dashboard
  title: Dashboard
  path: /dashboard
  slotBindings:
    - slot: header
      primitive: announcement-banner
      props:
        dismissible: true

Notes

Slot bindings only render registered primitives. There is no mechanism to inject arbitrary components or inline JSX from the manifest. This constraint is intentional: it keeps the manifest declarative and ensures all UI is auditable from the primitive registry.

See Slots and Bindings for the full guide including slot context, entity binding, and the blank-slot primitive.