Page
Page = title + list of components. All content lives in items, grouped by
section.
{
"contract_version": "0.1.0",
"page": {
"id": "home",
"title": "Home",
"items": [ /* components */ ],
"search": {
"endpoint": "/pages/home?q={query}",
"placeholder": "Search"
},
"toolbar": [
{
"icon": "plus",
"title": "Create",
"shortcut": "cmd+n",
"action": {
"type": "navigate",
"endpoint": "/pages/orders/new"
}
}
],
"refresh": true,
"refresh_interval": 0
}
}
| Field | Type | Description |
|---|---|---|
id | string | identifier |
title | string | navbar title |
items[] | array | page components |
search | object? | search bar; {query} substituted by the client |
toolbar[] | array? | actions on the navbar trailing side |
refresh | bool? | pull to refresh (default true) |
refresh_interval | int? | auto-refresh every N seconds; 0/nil — off |
source | object/array? | external data — see Data binding |
maps | object? | map transform tables |
Adding search
"search": {
"endpoint": "/pages/home?q={query}",
"placeholder": "Search"
}
{query} is substituted on input; the server returns a filtered page.
Adding a navbar button
A toolbar item = icon/title + action, with an optional shortcut. On macOS
it is mirrored into the window toolbar and the app menu.
Live page
refresh_interval: 5 — data is re-fetched every 5 seconds, changed rows update in
place. Use it only where data actually changes.
What the server controls, what the client controls
| Server | Client (cannot change) |
|---|---|
title, toolbar, search | back button, title style, navbar colors |