App Studio
Menu Items
Menu items are the clickable entries in the sidebar or top navigation — each item navigates to an AppPage when clicked. Items support labels, icons, badges, and role-based visibility.
Menu Item Config
// NavItem configuration
{
"type": "item",
"label": "Leads", // Display text in the sidebar
"icon": "users", // Font Awesome icon name (without "fa-" prefix)
"targetPageId": "leads-list", // AppPage pageId to navigate to
"badge": { // optional badge on the item
"value": "{{ service.GetUnreadCount() }}",
"variant": "danger" // "info" | "warning" | "danger" | "success"
},
"visibilityExpression": "{{ context.roles.includes('sales') }}", // optional
"tooltip": "View and manage sales leads" // shown on hover (useful in collapsed mode)
}
Menu Item Properties Reference
| Property | Type | Description |
|---|---|---|
type | "item" | Identifies this as a navigation item (vs. "group" or "divider") |
label | string | Text shown in the sidebar. Supports token expressions for dynamic labels. |
icon | string | Font Awesome icon name. See fontawesome.com/icons for the full list. |
targetPageId | string | The pageId of the AppPage to navigate to when clicked. |
badge | object | Optional notification badge with a value (supports tokens) and a color variant. |
visibilityExpression | string | Token expression — item hidden if evaluates to false. Role-based nav visibility. |
tooltip | string | Hover tooltip. Particularly useful in collapsed sidebar mode where label is hidden. |
openInNewTab | boolean | If true, navigating to this item opens the AppPage in a new browser tab. |
Dynamic Badge Values
Badges are a great way to show counts (unread messages, pending approvals) using data binding:
// Approval queue item with live count badge
{
"type": "item",
"label": "Approvals",
"icon": "check-circle",
"targetPageId": "approval-queue",
"badge": {
"value": "{{ service.GetPendingApprovalCount() }}",
"variant": "{{ service.GetPendingApprovalCount() > 10 ? 'danger' : 'warning' }}"
}
}
Divider Items
To add visual separation between navigation groups without a labeled header, use a divider:
// Divider between sections
{ "type": "divider" }