Application Schema (AppSchema)
Configure your entire application with navigation, branding, and global settings
Application Schema
The AppSchema defines the top-level configuration for your entire ObjectUI application, including navigation menus, branding, layout strategies, and global actions.
Overview
AppSchema provides a declarative way to configure:
- Navigation menus - Hierarchical menu structures with icons and badges
- Branding - Logo, title, favicon
- Layout strategies - Sidebar, header, or empty layout
- Global actions - User menu, global toolbar buttons
Interactive Examples
Navigation Menu Preview
Sidebar Navigation
A typical application sidebar menu structure with icons, groups, and badges
{
"type": "card",
"className": "w-64",
"children": [
{
"type": "stack",
"spacing": 1,
"children": [
{
"type": "flex",
"className": "items-center gap-2 px-3 py-2 rounded-md bg-accent text-accent-foreground",
"children": [
{
"type": "icon",
"name": "layout-dashboard",
"className": "h-4 w-4"
},
{
"type": "text",
"content": "Dashboard",
"className": "text-sm font-medium"
}
]
},
{
"type": "flex",
"className": "items-center gap-2 px-3 py-2 rounded-md hover:bg-accent/50",
"children": [
{
"type": "icon",
"name": "users",
"className": "h-4 w-4 text-muted-foreground"
},
{
"type": "text",
"content": "Contacts",
"className": "text-sm"
},
{
"type": "badge",
"label": "128",
"variant": "secondary",
"className": "ml-auto text-xs"
}
]
},
{
"type": "flex",
"className": "items-center gap-2 px-3 py-2 rounded-md hover:bg-accent/50",
"children": [
{
"type": "icon",
"name": "target",
"className": "h-4 w-4 text-muted-foreground"
},
{
"type": "text",
"content": "Opportunities",
"className": "text-sm"
}
]
},
{
"type": "separator",
"className": "my-2"
},
{
"type": "text",
"content": "Marketing",
"className": "px-3 text-xs font-semibold text-muted-foreground uppercase tracking-wider"
},
{
"type": "flex",
"className": "items-center gap-2 px-3 py-2 rounded-md hover:bg-accent/50",
"children": [
{
"type": "icon",
"name": "megaphone",
"className": "h-4 w-4 text-muted-foreground"
},
{
"type": "text",
"content": "Campaigns",
"className": "text-sm"
}
]
},
{
"type": "flex",
"className": "items-center gap-2 px-3 py-2 rounded-md hover:bg-accent/50",
"children": [
{
"type": "icon",
"name": "mail",
"className": "h-4 w-4 text-muted-foreground"
},
{
"type": "text",
"content": "Email Templates",
"className": "text-sm"
}
]
},
{
"type": "separator",
"className": "my-2"
},
{
"type": "flex",
"className": "items-center gap-2 px-3 py-2 rounded-md hover:bg-accent/50",
"children": [
{
"type": "icon",
"name": "settings",
"className": "h-4 w-4 text-muted-foreground"
},
{
"type": "text",
"content": "Settings",
"className": "text-sm"
}
]
}
]
}
]
}Application Header Bar
Application Header
Top bar with branding, global search, and user actions
{
"type": "flex",
"className": "items-center justify-between p-3 border rounded-lg bg-background",
"children": [
{
"type": "flex",
"className": "items-center gap-3",
"children": [
{
"type": "icon",
"name": "box",
"className": "h-6 w-6 text-primary"
},
{
"type": "text",
"content": "Acme CRM",
"className": "font-semibold text-lg"
}
]
},
{
"type": "flex",
"className": "items-center gap-2",
"children": [
{
"type": "button",
"label": "Quick Actions",
"variant": "outline",
"size": "sm",
"icon": "zap"
},
{
"type": "button",
"label": "Notifications",
"variant": "ghost",
"size": "sm",
"icon": "bell"
},
{
"type": "flex",
"className": "items-center gap-2 ml-2 pl-2 border-l",
"children": [
{
"type": "avatar",
"fallback": "JD",
"className": "h-8 w-8"
},
{
"type": "stack",
"spacing": 0,
"children": [
{
"type": "text",
"content": "John Doe",
"className": "text-sm font-medium leading-none"
},
{
"type": "text",
"content": "john@acme.com",
"className": "text-xs text-muted-foreground"
}
]
}
]
}
]
}
]
}Basic Usage
import type { AppSchema } from '@object-ui/types';
const app: AppSchema = {
type: 'app',
name: 'my-crm',
title: 'My CRM Application',
logo: '/logo.svg',
favicon: '/favicon.ico',
layout: 'sidebar',
menu: [
{
type: 'item',
label: 'Dashboard',
icon: 'layout-dashboard',
path: '/dashboard'
}
],
actions: [
{
type: 'user',
label: 'John Doe',
avatar: '/avatar.jpg'
}
]
};Properties
Basic Configuration
| Property | Type | Description |
|---|---|---|
type | 'app' | Component type identifier (required) |
name | string | Application system identifier |
title | string | Display title shown in browser |
description | string | Application description |
logo | string | Logo URL or icon name |
favicon | string | Favicon URL |
Layout Configuration
| Property | Type | Default | Description |
|---|---|---|---|
layout | 'sidebar' | 'header' | 'empty' | 'sidebar' | Global layout strategy |
Layout Options:
sidebar- Standard admin layout with left sidebar navigationheader- Top navigation bar onlyempty- No layout, pages handle their own structure
Navigation Menu
The menu property accepts an array of MenuItem objects:
interface MenuItem {
type?: 'item' | 'group' | 'separator';
label?: string;
icon?: string; // Lucide icon name
path?: string; // Route path
href?: string; // External link
children?: MenuItem[]; // Submenu items
badge?: string | number;
hidden?: boolean | string; // Visibility condition
}Menu Types
Item - Single navigation link
{
"type": "item",
"label": "Dashboard",
"icon": "layout-dashboard",
"path": "/dashboard",
"badge": "New"
}Group - Collapsible menu group
{
"type": "group",
"label": "Sales",
"icon": "dollar-sign",
"children": [
{ "type": "item", "label": "Leads", "path": "/leads" },
{ "type": "item", "label": "Deals", "path": "/deals" }
]
}Separator - Visual separator
{
"type": "separator"
}Global Actions
The actions property defines global toolbar buttons:
interface AppAction {
type: 'button' | 'dropdown' | 'user';
label?: string;
icon?: string;
onClick?: string;
avatar?: string; // For type='user'
description?: string; // For type='user'
items?: MenuItem[]; // For type='dropdown' or 'user'
shortcut?: string; // Keyboard shortcut
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
size?: 'default' | 'sm' | 'lg' | 'icon';
}Complete Example
const crm: AppSchema = {
type: 'app',
name: 'acme-crm',
title: 'Acme CRM',
description: 'Customer Relationship Management System',
logo: '/acme-logo.svg',
favicon: '/favicon.ico',
layout: 'sidebar',
menu: [
{
type: 'item',
label: 'Dashboard',
icon: 'layout-dashboard',
path: '/dashboard'
},
{
type: 'separator'
},
{
type: 'group',
label: 'Sales',
icon: 'dollar-sign',
children: [
{
type: 'item',
label: 'Leads',
icon: 'users',
path: '/leads',
badge: 12
},
{
type: 'item',
label: 'Opportunities',
icon: 'target',
path: '/opportunities'
},
{
type: 'item',
label: 'Quotes',
icon: 'file-text',
path: '/quotes'
}
]
},
{
type: 'group',
label: 'Marketing',
icon: 'megaphone',
children: [
{
type: 'item',
label: 'Campaigns',
path: '/campaigns'
},
{
type: 'item',
label: 'Email Templates',
path: '/templates'
}
]
},
{
type: 'separator'
},
{
type: 'item',
label: 'Settings',
icon: 'settings',
path: '/settings',
hidden: '${user.role !== "admin"}'
}
],
actions: [
{
type: 'button',
label: 'Quick Actions',
icon: 'zap',
variant: 'outline',
onClick: 'openQuickActions'
},
{
type: 'user',
label: 'John Doe',
avatar: '/avatars/john.jpg',
description: 'john@acme.com',
items: [
{
type: 'item',
label: 'Profile',
icon: 'user',
path: '/profile'
},
{
type: 'item',
label: 'Settings',
icon: 'settings',
path: '/settings'
},
{
type: 'separator'
},
{
type: 'item',
label: 'Logout',
icon: 'log-out',
path: '/logout'
}
]
}
]
};Runtime Validation
Use Zod validation to ensure your app configuration is correct:
import { AppSchema } from '@object-ui/types/zod';
const result = AppSchema.safeParse(myAppConfig);
if (result.success) {
console.log('Valid app configuration');
} else {
console.error('Validation errors:', result.error);
}Conditional Navigation
Use expression syntax to show/hide menu items based on user permissions:
{
"type": "item",
"label": "Admin Panel",
"path": "/admin",
"hidden": "${user.role !== 'admin'}"
}Use Cases
AppSchema is ideal for:
- Multi-page applications - Configure complex application structures with multiple routes
- Admin dashboards - Create comprehensive admin panels with role-based navigation
- CRM systems - Build customer relationship management interfaces
- Internal tools - Develop enterprise internal tools with centralized navigation
- SaaS products - Configure multi-tenant applications with customizable layouts
Best Practices
- Use semantic icons - Choose Lucide icons that clearly represent the section
- Group related items - Use menu groups to organize navigation
- Limit top-level items - Keep the main menu concise (5-7 items)
- Add badges for notifications - Show counts or status indicators
- Hide admin features - Use conditional visibility for role-based access
- Provide keyboard shortcuts - Add shortcuts for frequently used actions
Related
- Layout Schema - Page layout configuration
- Navigation Components - Navigation UI components
- Theme Schema - Application theming