Skip to main content
A folder’s index.ts can export a page instead of an action, see Routing. The folder then shows its subfolders and actions in a column on the left and the page on the right. A page puts display components (a table, tiles…) into a layout. It only displays, so there is no form and no Continue button.
The Users tab: Messages, Change role, Export users and Send welcome email in a left column; tiles with totals, a users table with linked names and row menus, and a paged activity table with a filter on the right

The Users folder of the demo app: its folder and actions on the left, the page in the basic layout on the right.

A page needs the display components it shows registered in components, see Display components, and a layout to put them in, see Layouts.

Write a page

Export app.definePage() from the folder’s index.ts. The handler returns a layout with the display components in it:
actions/users/index.ts
  • Every display component takes a label, shown as the heading above it (null for none), and its props.
  • Returning just the array, return [io.display.table(…)], puts it into the layout registered as basic.
  • Props are typed by each component’s schema, and the server checks them again before they reach the browser: props that do not fit show an error instead of the page.
  • The handler runs every time someone opens the folder; nothing is kept between visits.
  • The handler gets ctx like an action: ctx.user is who opened the page and ctx.params the query string of the link (/groups/users?role=admin). ctx.page.slug is the folder the page stands for: users.
  • app.definePage() belongs only in a folder’s index.ts; anywhere else it stops the app at start.
  • Its const ends in Page, usersPage, as an action’s ends in Action; the file stays index.ts.

Layouts

The handler returns the display components inside a layout, the frame that places them. Every layout is a package registered in layouts, the basic one too:
app.ts
See Layout components for the layouts there are and how to write your own.