Page registration
Capsule supports two page models, and most real apps use both. The usual split is simple. Use the Python DSL for dashboards, metrics, settings, tables, and task views. Use React when the page starts to feel like a richer application surface, such as a mailbox, approval queue, or list-detail workflow. Both page types can be public or gated to signed-in users of the deployed app withaccess="authenticated".
Worked example
A strong Capsule app often uses both page models at once:- use the DSL for dashboards, metrics, settings, and task views
- use React for richer list/detail or workflow-heavy surfaces
Python DSL pages
| Argument | Meaning |
|---|---|
name | Sidebar label |
icon | Icon name |
order | Explicit page ordering |
access | "public" for open pages, or "authenticated" for signed-in users of this app |
React pages
| Argument | Meaning |
|---|---|
name | Sidebar label |
icon | Icon name |
component | Path to the TSX component |
packages | Extra npm packages for the page bundle |
order | Explicit page ordering |
access | "public" for open pages, or "authenticated" for signed-in users of this app |
DSL widgets
The Python DSL is deliberately small. You compose a page from a few primitives rather than learning a big UI framework.Layout
| Widget | Purpose |
|---|---|
cpsl.ui.Page(children) | Root page container |
cpsl.ui.Row(children) | Horizontal grouping |
cpsl.ui.Column(children) | Vertical grouping |
cpsl.ui.Card(title=None, children=None) | Card wrapper |
cpsl.ui.Divider() | Visual separator |
cpsl.ui.Text(content, style=None) | Text element |
Data display
| Widget | Purpose |
|---|---|
Metric(...) | KPI or summary stat |
Table(...) | Table from collection, data source, or inline rows |
Chart(...) | Chart from a data source |
Settings widgets
| Widget | Purpose |
|---|---|
Toggle(label, setting=...) | Boolean setting |
TextInput(label, setting=..., multiline=False, placeholder=None) | String setting |
NumberInput(label, setting=..., min=None, max=None, step=None) | Numeric setting |
Select(label, setting=...) | Setting with predefined options |
Task UI
| Widget | Purpose |
|---|---|
TaskBoard(...) | Kanban-style task board |
TaskBoardColumn(label, statuses) | Custom task-board column group |
Widget notes
Metriccan display a literalvalueor bind todataplusfield.Tablecan bind to a collection, a data handler, or inlinerows.Chartbinds to a named data source and supportsline,bar,pie,scatter, andarea.- Passing a
CollectionReftoTable(...)lets Capsule inherit collection metadata automatically.
React page runtime
React pages are built with the@capsule/page runtime. The most common helpers are:
useData(...)useCollection(...)useTheme()useCapsule()for the current app user pluslogin()/logout()
access="authenticated" pages, Capsule handles the sign-in gate before the React page loads. Inside the page, useCapsule().user is the signed-in user for this app. If you want a public page to prompt for sign-in, useCapsule().login() opens the app sign-in flow.
React pages are the right choice when you need custom interactivity or external packages. The Python DSL is usually faster when metrics, tables, charts, and settings widgets are enough.
Naming pitfall
Do not confuse:cpsl.Columnfor collection schemacpsl.ui.Columnfor page layout