App
App protocol schemas
Base Navigation Item Schema Shared properties for all navigation types.
NAMING CONVENTION: Navigation item IDs are used in URLs and configuration and must be lowercase snake_case.
@example Good IDs
- 'menu_accounts'
- 'page_dashboard'
- 'nav_settings'
@example Bad IDs (will be rejected)
- 'MenuAccounts' (PascalCase)
- 'Page Dashboard' (spaces)
Source: packages/spec/src/ui/app.zod.ts
TypeScript Usage
import { ActionNavItemSchema, AppSchema, AppBrandingSchema, AppContextSelectorSchema, ComponentNavItemSchema, DashboardNavItemSchema, GroupNavItemSchema, NavigationAreaSchema, NavigationContributionSchema, NavigationItemSchema, ObjectNavItemSchema, PageNavItemSchema, ReportNavItemSchema, UrlNavItemSchema } from '@objectstack/spec/ui';
import type { ActionNavItem, App, AppBranding, AppContextSelector, ComponentNavItem, DashboardNavItem, GroupNavItem, NavigationArea, NavigationContribution, NavigationItem, ObjectNavItem, PageNavItem, ReportNavItem, UrlNavItem } from '@objectstack/spec/ui';
// Validate data
const result = ActionNavItemSchema.parse(data);ActionNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'action' | ✅ | |
| actionDef | { actionName: string; params?: Record<string, any> } | ✅ | Action definition to execute when clicked |
App
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | App unique machine name (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | App display label |
| version | never | optional | [REMOVED] App.version was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — no consumer in framework or objectui). An app is versioned by its owning package: use manifest.version. Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| description | string | Record<string, string> | optional | App description |
| icon | string | optional | App icon used in the App Launcher |
| branding | { primaryColor?: string; accentColor?: string; logo?: string; favicon?: string } | optional | App-specific branding |
| active | boolean | optional | Whether the app is enabled |
| isDefault | boolean | optional | Is default app |
| hidden | boolean | optional | Hide from the App Switcher; the shell surfaces hidden apps via the avatar menu instead (navigation only — never an access gate) |
| _unpublished | boolean | optional | Machine-managed publish gate (ADR-0045 §3) — true = unpublished, externally unobservable. Written by AI materialization, cleared by publish-drafts. Never authored. |
| navigation | ({ id: string; label: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +7 more)[] | optional | Full navigation tree for the app sidebar |
| areas | { id: string; label: string | Record<string, string>; icon?: string; description?: string | Record<string, string>; … }[] | optional | Navigation areas for partitioning navigation by business domain |
| contextSelectors | { id: string; label: string | Record<string, string>; icon?: string; optionsSource: object; … }[] | optional | App-level scope dropdowns whose value is injected into nav items as {<id>} template vars |
| homePageId | never | optional | [REMOVED] app.homePageId was removed in @objectstack/spec 17.0.0 (#4667, #4709, ADR-0049). objectui's console did read it before v17 (resolveLandingRoute), so this key had a consumer — it was retired because the capability is better expressed on the navigation item itself than as an ID cross-reference that silently falls back when it dangles. An app's landing page IS its first navigation item (by order), and the root landing follows isDefault routing. Delete the key; to change where an app opens, reorder navigation so the intended entry is first, and set isDefault on the app that should own the root landing. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| requiredPermissions | string[] | optional | Permissions required to access this app |
| objects | never | optional | [REMOVED] App.objects was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — never read; the spec itself labelled it "config file convenience"). Objects belong to the stack (defineStack({ objects })); an app reaches them through its navigation items. Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| apis | never | optional | [REMOVED] App.apis was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — never read). Delete the key and declare the endpoint one level up, on the STACK: defineStack({ apis }). That surface EXECUTES from protocol 17 (#5040). Between #4936 and the executor landing it was refused wholesale — nothing mounted a declared path, so every key including authRequired parsed and gated nothing — and that blanket refusal is now narrowed to five per-endpoint publish gates (namespace, supported target, mapping, policy, uniqueness): an endpoint that passes them is mounted and serves traffic as soon as the stack is published. Two things to get right when you move it: the path must sit inside your own carve-out, /api/v1/apps/<manifest.namespace>/<subpath> with an explicit manifest.namespace (ADR-0121 D1/D2), and authRequired defaults to true — an explicit false is the only thing that opens anonymous access, and ADR-0121 D6 then requires an armed rateLimit: { enabled: true, windowMs, maxRequests }. Read the declarative-apis-endpoints-live entry of the protocol upgrade guide first; it is a security review, not a rename. A route that genuinely needs handler CODE still belongs in a plugin manifest contributes.routes entry. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| sharing | never | optional | [REMOVED] App.sharing was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit / ADR-0049 enforce-or-remove) — no public-app route ever read it, so it declared sharing that did not exist. Public access is granted per FORM VIEW (FormView.sharing, the public-data-collection surface). Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| embed | never | optional | [REMOVED] App.embed was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit / ADR-0049) — no iframe route ever read it. Embedding is a per-form-view surface (FormView.sharing), not an app-level switch. Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| mobileNavigation | never | optional | [REMOVED] App.mobileNavigation was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — fully unimplemented; no renderer, including packages/mobile, ever read it). Delete the key; the block returns if/when a real mobile navigation ships. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| defaultAgent | string | optional | Platform agent bound to this app's ambient chat ('ask' is the implicit default; 'build' for authoring surfaces) — ADR-0063 §1 |
| aria | never | optional | [REMOVED] App.aria was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — no renderer read app-level ARIA attributes). Declare aria on the page component that renders the DOM node instead (page.components[].aria; page.aria and the list view aria are live too). Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically. |
| protection | { lock: Enum<'none' | 'no-overlay' | 'no-delete' | 'full'>; reason: string; docsUrl?: string } | optional | Package author protection block — lock policy for this app. |
| _lock | Enum<'none' | 'no-overlay' | 'no-delete' | 'full'> | optional | Item-level lock — controls overlay & delete (ADR-0010). |
| _lockReason | string | optional | Human-readable reason shown when a write is refused by _lock. |
| _lockSource | Enum<'artifact' | 'package' | 'env-forced'> | optional | Layer that set _lock (artifact | package | env-forced). |
| _provenance | Enum<'package' | 'org' | 'env-forced'> | optional | Origin of the item (package | org | env-forced). |
| _packageId | string | optional | Owning package machine id. |
| _packageVersion | string | optional | Owning package version. |
| _lockDocsUrl | string | optional | Optional documentation link surfaced next to _lockReason. |
AppBranding
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| primaryColor | string | optional | Primary theme color hex code |
| accentColor | string | optional | Accent color hex code (highlights, active states). Declared to match the objectui ConsoleLayout read of branding.accentColor (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| logo | string | optional | Custom logo URL for this app |
| favicon | string | optional | Custom favicon URL for this app |
AppContextSelector
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Selector id; selected value is exposed as the nav template var {<id>} |
| label | string | Record<string, string> | ✅ | Dropdown label |
| icon | string | optional | Icon name |
| optionsSource | { endpoint: string; valueKey: string; labelKey: string; filter?: object[] } | ✅ | Option data source |
| allValue | string | ✅ | Sentinel value meaning "no concrete selection yet" (empty string is almost always right) |
| persist | Enum<'query' | 'session' | 'none'> | ✅ | Persist selection via URL query, sessionStorage, or not at all |
ComponentNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'component' | ✅ | |
| componentRef | string | ✅ | Component registry key (e.g. "metadata:directory") |
| params | Record<string, any> | optional | Props passed to the component |
DashboardNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'dashboard' | ✅ | |
| dashboardName | string | ✅ | Target dashboard name |
GroupNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'group' | ✅ | |
| expanded | boolean | optional | Default expansion state in sidebar |
NavigationArea
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique area identifier (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Area display label |
| icon | string | optional | Area icon name |
| description | string | Record<string, string> | optional | Area description |
| navigation | ({ id: string; label: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +7 more)[] | ✅ | Navigation items within this area |
NavigationContribution
A navigation contribution: a package injecting nav items into an app it does not own (ADR-0029 D7)
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| app | string | ✅ | Target app name to contribute navigation into (e.g. "setup") |
| group | string | optional | Target group nav-item id to append into (e.g. "group_integrations"); omit to append at the app top level |
| priority | integer | optional | Merge priority within the target group — lower applied first (matches object extender priority) |
| items | ({ id: string; label: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +7 more)[] | ✅ | Navigation items contributed into the target app/group |
NavigationItem
Union Options
This schema accepts one of the following structures:
Option 1
Type: object
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'object' | ✅ | |
| objectName | string | ✅ | Target object name |
| viewName | string | optional | Default list view to open. Defaults to "all". Ignored when recordId is set. |
| recordId | string | optional | Navigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}. |
| recordMode | Enum<'view' | 'edit'> | optional | Open the record in view (default) or edit mode. Only meaningful when recordId is set. |
| filters | Record<string, string> | optional | URL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName. |
| runAction | string | optional | Auto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action", #4848). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId. |
| children | [NavigationItem](#navigationitem)[] | optional | Child navigation items (e.g. specific views) |
Option 2
Type: dashboard
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'dashboard' | ✅ | |
| dashboardName | string | ✅ | Target dashboard name |
Option 3
Type: page
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'page' | ✅ | |
| pageName | string | ✅ | Target custom page component name |
| params | Record<string, any> | optional | Parameters passed to the page context |
Option 4
Type: url
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'url' | ✅ | |
| url | string | ✅ | Target external URL |
| target | Enum<'_self' | '_blank'> | optional | Link target window |
Option 5
Type: report
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'report' | ✅ | |
| reportName | string | ✅ | Target report name |
Option 6
Type: action
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'action' | ✅ | |
| actionDef | { actionName: string; params?: Record<string, any> } | ✅ | Action definition to execute when clicked |
Option 7
Type: component
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'component' | ✅ | |
| componentRef | string | ✅ | Component registry key (e.g. "metadata:directory") |
| params | Record<string, any> | optional | Props passed to the component |
Option 8
Type: separator
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| type | 'separator' | ✅ | |
| id | string | optional | Optional id for the separator |
| order | number | optional | Sort order within the same level (lower = first) |
Option 9
Type: group
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'group' | ✅ | |
| expanded | boolean | optional | Default expansion state in sidebar |
| children | [NavigationItem](#navigationitem)[] | ✅ | Child navigation items |
ObjectNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'object' | ✅ | |
| objectName | string | ✅ | Target object name |
| viewName | string | optional | Default list view to open. Defaults to "all". Ignored when recordId is set. |
| recordId | string | optional | Navigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}. |
| recordMode | Enum<'view' | 'edit'> | optional | Open the record in view (default) or edit mode. Only meaningful when recordId is set. |
| filters | Record<string, string> | optional | URL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName. |
| runAction | string | optional | Auto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action", #4848). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId. |
PageNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'page' | ✅ | |
| pageName | string | ✅ | Target custom page component name |
| params | Record<string, any> | optional | Parameters passed to the page context |
ReportNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'report' | ✅ | |
| reportName | string | ✅ | Target report name |
UrlNavItem
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Unique identifier for this navigation item (lowercase snake_case) |
| label | string | Record<string, string> | ✅ | Display proper label |
| icon | string | optional | Icon name |
| order | number | optional | Sort order within the same level (lower = first) |
| badge | string | number | optional | Badge text or count displayed on the item |
| badgeVariant | Enum<'default' | 'secondary' | 'destructive' | 'outline'> | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). |
| visible | string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } | optional | Visibility predicate (CEL). e.g. P'org_admin' in current_user.positions |
| requiredPermissions | string[] | optional | Permissions required to access this item |
| requiresObject | string | optional | Hide/disable this entry unless the named object is registered in the runtime |
| requiresService | string | optional | Hide/disable this entry unless the named kernel service is registered |
| type | 'url' | ✅ | |
| url | string | ✅ | Target external URL |
| target | Enum<'_self' | '_blank'> | optional | Link target window |