Frontend
Pages
A page is the frontend's handler: a route that resolves into a view. It shares the handler contract you already know, with one addition, render, and one convenience, head. Data still comes from handle.
#The page contract
Mark a class with @Page(path) (or register a definePage). Three methods, all but render optional:
| Method | Type | Description |
|---|---|---|
| handle(context) | loader | Load the page data before render; its return is available as data. Optional. |
| render(context)* | view | Return the React node. Receives { data, event, container, statusCode }. |
| head(context) | metadata | Return the document head for this page (title, meta, ...). Optional. |
import { Page, IPage, ReactIncomingEvent, HeadContext } from '@stone-js/use-react'
import { JSX } from 'react'
@Page('/tasks')
export class TasksPage implements IPage<ReactIncomingEvent> {
// Optional loader: runs before render (server or client).
handle ({ tasks }: { tasks: TaskService }) {
return tasks.list()
}
// Optional document head for this page.
head (): HeadContext {
return { title: 'Tasks', description: 'Everything to do.' }
}
// Required: return the view.
render ({ data }: { data: Task[] }): JSX.Element {
return <ul>{data.map((t) => <li key={t.id}>{t.title}</li>)}</ul>
}
}import { definePage } from '@stone-js/use-react'
const TasksPage = ({ tasks }) => ({
handle: () => tasks.list(),
head: () => ({ title: 'Tasks', description: 'Everything to do.' }),
render: ({ data }) => <ul>{data.map((t) => <li key={t.id}>{t.title}</li>)}</ul>
})
export const pages = [definePage(TasksPage, { path: '/tasks' }, true)]#The render context
render receives the data from handle, the event, the container and a status code. Reading data is usually done straight from the argument, or with useData() deeper in the tree.