Frontend
Components & links
Below pages and layouts, you write ordinary React components. The framework adds a few primitives for links and outlets, and a set of hooks so a component can reach the router, the container, config and the current data without prop drilling.
#Framework components
| Component | Type | Description |
|---|---|---|
| <StoneLink to={} /> | link | Client-side navigation in SPA/SSR, a normal link where that is right. |
| <StoneOutlet> | outlet | Where a layout renders its page. |
| <StonePage /> | page mount | Mounts a resolved page (advanced; used internally and for custom shells). |
import { StoneLink } from '@stone-js/use-react'
export function TaskRow ({ task }: { task: Task }) {
return <StoneLink to={`/tasks/${task.id}`}>{task.title}</StoneLink>
}#Hooks
Hooks are how a component reaches the application. They work the same on the server render and in the browser.
| Hook | Type | Description |
|---|---|---|
| useData<T>() | () => T | The current page data (from the page handle). |
| useRoute() | () => Route | The active route: name, params, path. |
| useRouter() | () => Router | The router: generate URLs, navigate. |
| useHead(head) | (head) => void | Set document head from within a component. |
| useConfig() | () => Config | The read-only Blueprint config. |
| useService(alias) | (alias) => T | Resolve a service from the container. |
| useContainer() | () => Container | The container itself (advanced). |
| useEventEmitter() | () => Emitter | Emit and listen to domain events. |
| useEvent() | () => IncomingEvent | The current incoming event (the intention being rendered). |
| useRawEvent() | () => raw | The platform’s raw cause (escape hatch; rarely needed). |
| useBlueprint() | () => Blueprint | The frozen manifest, for advanced introspection. |
| useRuntime() | () => Runtime | The React runtime (SSR/CSR state). |
| useStone() | () => context | The full Stone context, when you need several of the above at once. |
import { useData, useRouter } from '@stone-js/use-react'
export function TaskCount () {
const tasks = useData<Task[]>() ?? []
const router = useRouter()
return <a href={router.generate({ name: 'tasks.list' })}>{tasks.length} tasks</a>
}#Everything else is React
Beyond these, there is nothing special: your components are plain React, free to use hooks, context and libraries as usual. The framework primitives exist only where the app boundary needs to show through.