alepha@docs:~/docs/reference/primitives$
cat $page.md3 min read
#$page
#Import
typescript
1import { $page } from "alepha/react/router";
#Overview
Main primitive for defining a React route in the application.
The $page primitive is the core building block for creating type-safe, SSR-enabled React routes. It provides a declarative way to define pages with powerful features:
Routing & Navigation
- URL pattern matching with parameters (e.g.,
/users/:id) - Nested routing with parent-child relationships
- Type-safe URL parameter and query string validation
Data Loading
- Server-side data fetching with the
loaderfunction - Automatic serialization and hydration for SSR
- Access to request context, URL params, and parent data
Component Loading
- Direct component rendering or lazy loading for code splitting
- Client-only rendering when browser APIs are needed
- Automatic fallback handling during hydration
Performance Optimization
- Static generation for pre-rendered pages at build time
- Server-side caching with configurable TTL and providers
- Code splitting through lazy component loading
Error Handling
- Custom error handlers with support for redirects
- Hierarchical error handling (child → parent)
- HTTP status code handling (404, 401, etc.)
Page Animations
- CSS-based enter/exit animations
- Dynamic animations based on page state
- Custom timing and easing functions
Lifecycle Management
- Server response hooks for headers and status codes
- Page leave handlers for cleanup (browser only)
- Permission-based access control
#Options
| Option | Type | Required | Description |
|---|---|---|---|
name |
string |
No | Identifier name for the page |
path |
string |
No | Add a pathname to the page |
schema |
TConfig |
No | Add an input schema to define: - params: parameters from the pathname |
use |
Middleware[] |
No | Middleware to apply to the loader function |
loader |
Object |
No | Load data before rendering the page |
props |
Object |
No | Default props to pass to the component when rendering the page |
component |
FC<TProps & TPropsParent> |
No | The component to render when the page is loaded |
lazy |
Object |
No | Lazy load the component when the page is loaded |
children |
Array<PagePrimitive> | (() => Array<PagePrimitive>) |
No | Attach child pages to create nested routes |
parent |
PagePrimitive<PageConfigSchema, TPropsParent, any> |
No | Define a parent page for nested routing. |
can |
Object |
No | Function to determine if the page can be accessed |
errorHandler |
ErrorHandler |
No | Catch any error from the loader function or during rendering |
entries |
Array<Partial<PageRequestConfig<TConfig>>> |
No | If true, the page will be considered as a static page, immutable and cacheable |
client |
boolean | ClientOnlyProps |
No | If true, force the page to be rendered only on the client-side (browser) |
onServerResponse |
Object |
No | Called before the server response is sent to the client |
onEnter |
Object |
No | Called when user enters the page |
onLeave |
Object |
No | Called when user leaves the page |
animation |
PageAnimation |
No | Add a css animation when the page is loaded or unloaded |
head |
Head | ((props: TProps, previous?: Head) => Head) |
No | Head configuration for the page (title, meta tags, etc.) |
#Examples
Simple page with data fetching
typescript
1const userProfile = $page({ 2 path: "/users/:id", 3 schema: { 4 params: t.object({ id: t.integer() }), 5 query: t.object({ tab: t.optional(t.text()) }) 6 }, 7 loader: async ({ params }) => { 8 const user = await userApi.getUser(params.id); 9 return { user };10 },11 lazy: () => import("./UserProfile.tsx")12});
Nested routing with error handling
typescript
1const projectSection = $page({ 2 path: "/projects/:id", 3 children: () => [projectBoard, projectSettings], 4 loader: async ({ params }) => { 5 const project = await projectApi.get(params.id); 6 return { project }; 7 }, 8 errorHandler: (error) => { 9 if (HttpError.is(error, 404)) {10 return <ProjectNotFound />;11 }12 }13});
Static generation with caching
typescript
1const blogPost = $page({ 2 path: "/blog/:slug", 3 static: { 4 entries: posts.map(p => ({ params: { slug: p.slug } })) 5 }, 6 loader: async ({ params }) => { 7 const post = await loadPost(params.slug); 8 return { post }; 9 }10});