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.