smolter
Guides

Routing

Choose a manual route table or flat files. Both produce the same route objects.

Compatibility

ReactAvailable in this renderer's browser integration.
React SSRAvailable to this renderer's SSR integration; browser event handlers run after hydration.
PreactAvailable in this renderer's browser integration.
Preact SSRAvailable to this renderer's SSR integration; browser event handlers run after hydration.

Manual paths

Static segments match exactly; :id captures one non-empty segment; a terminal * captures the remaining path. One trailing slash is ignored. Query strings do not select routes. First match wins.

const routes = [
  defineRoute("/tasks/search", search),
  defineRoute("/tasks/:id", detail),
  defineRoute("/files/*", files),
];

Flat files

The Vite plugin discovers immediate route folders or flat module files. Dots create URL segments, $id creates a parameter, and a terminal $ creates a splat. _index is an index route. Leading underscore segments are pathless; trailing underscores are removed. These are URL conventions, not nested component layouts.

src/routes/_index/route.ts          → /
src/routes/tasks._index/route.ts    → /tasks
src/routes/tasks.search/route.ts    → /tasks/search
src/routes/tasks.$id/route.ts       → /tasks/:id
src/routes/files.$/route.ts         → /files/*

Enable the plugin

Install Vite 8 or newer. Import the generated route table from the virtual module. Re-export server handlers from separate files so server implementation code can be excluded from browser builds.

import { defineConfig } from "vite";
import { fileRouter } from "@kasperrt/smolter/react/vite";

export default defineConfig({
  plugins: [fileRouter({ directory: "src/routes" })],
});

// main.ts
import routes from "virtual:smolter/routes";

Limits

File routing does not support arbitrary directory nesting, optional segments, parentheses, bracket escapes, or nested layout rendering. Duplicate or ambiguous parameter patterns return an error. Manual ordering remains your responsibility; file discovery sorts static routes ahead of dynamic routes.