Pages
Pages & loaders
x supports two page modes — static prerendering and server-side rendering — both powered by loaders.
Page modes
By default, pages are server-rendered (SSR). Export mode = "static" to prerender at build time.
Static pages
Static pages are rendered at build time and exported as HTML. Use this for marketing pages, blog posts, or any content that doesn't need per-request rendering.
src/pages/about.tsx
import type { RouteProps } from "@thexjs/core";export const mode = "static";export default function About({}: RouteProps) { return ( <div className="max-w-2xl mx-auto py-12"> <h1 className="text-4xl font-bold">About</h1> <p className="mt-4 text-muted-foreground"> This page is prerendered at build time. </p> </div> );}Server pages with loaders
Server pages (the default) run a loader function on every request. The loader can fetch data, query a database, or call an external API.
src/pages/products.tsx
import type { RouteProps, LoaderArgs } from "@thexjs/core";export async function loader({ request }: LoaderArgs) { const res = await fetch("https://api.example.com/products"); const products = await res.json(); return { products };}export default function Products({ loaderData }: RouteProps<typeof loader>) { return ( <div> <h1 className="text-3xl font-bold">Products</h1> <ul className="mt-6 space-y-4"> {loaderData.products.map((p: any) => ( <li key={p.id} className="rounded-xl border border-border bg-card p-4"> <h2 className="font-semibold">{p.name}</h2> <p className="text-sm text-muted-foreground">{p.price}</p> </li> ))} </ul> </div> );}Loader with dynamic params
Combined with dynamic routing, loaders receive params parsed from the URL path.
src/pages/products/[id].tsx
import type { RouteProps, LoaderArgs } from "@thexjs/core";export async function loader({ params }: LoaderArgs) { const product = await db.query( "SELECT * FROM products WHERE id = ?", [params.id] ); if (!product) throw new Response(null, { status: 404 }); return { product };}export default function ProductDetail({ loaderData }: RouteProps<typeof loader>) { const { product } = loaderData; return ( <div> <h1 className="text-3xl font-bold">{product.name}</h1> <p className="mt-2 text-muted-foreground">{product.description}</p> <p className="mt-4 text-2xl font-bold text-primary">${product.price}</p> </div> );}RouteProps type
The RouteProps type provides typed access to loaderData, params, and request. Pass your loader function as the type parameter for full type safety.
type usage
import type { RouteProps } from "@thexjs/core";// loaderData is automatically typed via the genericexport default function Page({ loaderData, params, request }: RouteProps<typeof loader>) { // loaderData has the return type of loader() // params has the dynamic segment types // request is the standard Request object}