ObjectOS
구축인터페이스

Pages

Free-form layouts composed from regions, components, and local state — plus Markdown doc pages that ship inside your package.

Pages

A page is a free-form container. Unlike a view, which is bound to a single object, a page combines multiple components, embeds views, and manages local state — your home screens, custom record layouts, and utility panels.

const homePage = {
  name: 'sales_home',
  label: 'Sales Home',
  type: 'home',
  regions: [
    { name: 'header', width: 'full', components: [
      { type: 'metric_card', id: 'total_revenue', label: 'Total Revenue',
        properties: { object: 'opportunity', field: 'amount', aggregate: 'sum', format: 'currency' } },
    ]},
    { name: 'main', width: 'large', components: [
      { type: 'list_view', id: 'recent_deals', label: 'Recent Deals',
        properties: { object: 'opportunity', view: 'recent_open', limit: 10 } },
    ]},
  ],
}

Page properties

PropertyTypeRequiredDescription
namestringyesMachine name (snake_case)
labelstringyesDisplay label
typeenumPage type (default 'record', see below)
objectstringAssociated object (for record type)
templatestringLayout template name (default 'default')
regionsPageRegion[]Layout zones with components
variablesPageVariable[]Local state variables
isDefaultbooleanIs the default page for its type
assignedProfilesstring[]Profiles that can access this page

Page types

TypeUse for
recordCustom detail pages tied to one object's records
homeApp landing / entry points
appGeneral application layouts
utilityTools, settings, wizards
listData-driven interface surfaces

Only these five types are valid — earlier roadmap types that never shipped a renderer were removed from the schema.

Regions

Regions are the layout zones; each holds components:

regions: [
  { name: 'sidebar', width: 'small', components: [/* … */] },
  { name: 'content', width: 'large', components: [/* … */] },
]

width accepts 'small', 'medium', 'large', or 'full'.

Components

Components are the building blocks inside regions:

{
  type: 'chart',
  id: 'revenue_chart',
  label: 'Revenue Trend',
  properties: { chartType: 'line', object: 'opportunity',
                categoryField: 'close_date', valueField: 'amount' },
  events: { onClick: "navigate_to('opportunity_detail', { id: $event.id })" },
  visibility: "os.user.profile == 'sales_manager'",
}
PropertyTypeDescription
typestringStandard component type or a custom string
idstringUnique component instance id
propertiesobjectComponent-specific configuration
eventsobjectEvent handlers (action expressions)
visibilitystringCEL visibility predicate
style / classNameAd-hoc CSS
responsiveStylesobjectPreferred styling channel: desktop-first per-breakpoint style maps (large base, then medium / small / xsmall overrides), compiled to scoped CSS — prefer design tokens like var(--space-8)

The standard, namespaced component types:

NamespaceTypes
Structurepage:header, page:footer, page:sidebar, page:tabs, page:accordion, page:card, page:section
Record contextrecord:details, record:highlights, record:related_list, record:activity, record:chatter, record:path, record:alert, record:quick_actions, record:reference_rail, record:history
Navigationapp:launcher, nav:menu, nav:breadcrumb
Utilityglobal:search, global:notifications, user:profile
AIai:chat_window, ai:suggestion
Elementselement:text, element:number, element:image, element:divider, element:button, element:filter, element:form, element:record_picker, element:text_input

Components may also carry dataSource (per-element object binding for multi-object pages), responsive, and aria configuration. Custom string types are accepted for project-specific widgets.

Variables

Pages hold local state shared across components:

variables: [
  { name: 'selected_tab', type: 'string', defaultValue: 'overview' },
  { name: 'date_range',   type: 'object', defaultValue: { start: null, end: null } },
]

type accepts 'string' (default), 'number', 'boolean', 'object', 'array', or 'record_id'.

A record-type page is the supported path for bespoke record layouts — reach for it when the roles-derived detail page (see Forms) isn't enough. Compose record:highlights in a full-width header, record:details and record:activity in a sidebar, and record:related_list components in the main region.

Surface a page from an app with a page navigation entry, or make it the app's landing page via homePageId.

Doc pages

A doc is a page of package documentation: plain Markdown files in a flat src/docs/ directory, compiled into the package artifact and rendered in the console at /docs/<name>. Docs also ground the AI assistant when it answers questions about your package.

src/docs/
  crm_index.md            → doc name "crm_index"
  crm_user_guide.md       → doc name "crm_user_guide"

The filename stem becomes the doc name — no directory taxonomy, no ordering file. The flat layout keeps cross-references stable: links resolve by basename, never by path.

RuleDetail
Namingsnake_case, and the build lint requires a namespace prefix (crm_user_guide, not user_guide)
FrontmatterOptional; title and description are read. Title resolves: frontmatter → first # heading → doc name
Cross-referencesPlain relative links ([overview](./crm_index.md)) — rewritten to /docs/<target> in console, native on GitHub. Broken same-package links fail the build
MarkdownCommonMark + GFM: tables, fenced code with highlighting, heading anchors, GitHub alerts (> [!TIP])
Rejected at buildMDX / embedded components (docs are data, not code — a trust boundary) and image references (no asset service yet; fail fast beats broken images)

Doc resolution is package-scoped: two installed packages may each ship a doc with the same bare name and coexist — neither overwrites the other.

For dynamic content — a live flow diagram, a record table — don't try to embed a component. Link to the metadata by URL; the platform renders the live view, the doc just points at it.

Where to go next

PageWhy
AppsPut pages in navigation, set homePageId
ViewsThe object surfaces pages embed
FormsRoles-derived record layouts vs custom record pages
DashboardsAnalytics-focused layout instead of free-form
Actionselement:button targets and modal-type actions
AI BuilderGenerate page metadata by chat

On this page