Getting started
Choose React or Preact, register your routes, and mount the provider.
Compatibility
Install
Install the router and the framework you use. Framework peers are optional; choosing React does not install Preact. Smolter’s Vite plugin uses its own pinned stable TypeScript 6 compiler API (typescript-compiler) for typed prefetch selection. Your application can keep TypeScript 7; no compiler downgrade or peer installation is required. The compiler does not enter browser bundles.
pnpm add @kasperrt/smolter react react-dom
# Or: pnpm add @kasperrt/smolter preact
# With Smolter’s Vite plugin:
pnpm add -D vite typescriptDefine the data
Put browser reads in clientLoader.ts. Replace this array with a request to your API when needed.
// routes/tasks/clientLoader.ts
export function clientLoader() {
return { tasks: [{ id: "1", title: "Try smolter" }] };
}Render the result
Re-export the loader from the route module. The type-only import connects useLoaderData to its return type.
// routes/tasks/route.tsx
import { useLoaderData } from "@kasperrt/smolter/react";
import type { clientLoader } from "./clientLoader";
export { clientLoader } from "./clientLoader";
export default function Tasks() {
const data = useLoaderData<typeof clientLoader>();
return <ul>{data?.tasks.map((task) => (
<li key={task.id}>{task.title}</li>
))}</ul>;
}Register a route
Keep the data handler beside the page. defineRoute retains its handler types. Manual routes use the first matching pattern, so put static paths before dynamic paths.
import { createDataRouter, defineRoute } from "@kasperrt/smolter/react";
import * as tasks from "./routes/tasks/route";
export const router = createDataRouter([
defineRoute("/tasks", tasks),
], { browser: true });Render
Create the router outside render. RouterProvider loads the current route; Routes renders its view. Mount App with React’s createRoot or Preact’s render, then open /tasks.
import { RouterProvider, Routes } from "@kasperrt/smolter/react";
import { router } from "./router";
export function App() {
return <RouterProvider router={router}>
<Routes fallback={<p>Page not found.</p>} />
</RouterProvider>;
}Next steps
Continue with the guides for reading data, handling mutations and background requests.