Skip to content
Ilha
Esc
navigateopen⌘Jpreview
On this page

Router overview

An isomorphic router for ilha apps — synchronous HTML on the server, signal-driven SPA navigation in the browser.

@ilha/router is an isomorphic router for ilha apps: synchronous HTML on the server, signal-driven SPA navigation in the browser. It is a separate package from ilha, so you only add it when you need multi-page routing.

Every route is an ilha island. The router matches URLs, runs loaders, and mounts the active page. Route context (routePath, routeParams, and related signals) uses context(), so any island can read the current route without extra wiring.

Install

npm install @ilha/router
pnpm add @ilha/router
yarn add @ilha/router
bun add @ilha/router

Import paths

Import path Use it for
@ilha/router Runtime router, loaders, navigation helpers, route context, and built-in islands.
@ilha/router/vite Vite file-system routing plugin.
@ilha/router/rspack Rspack file-system routing plugin.
@ilha/router/rolldown Rolldown file-system routing plugin.
@ilha/router/server-island Client proxy factory for server-defined islands (used by generated code).
@ilha/router/ssr Production SSR endpoints middleware — POST /__ilha/frame and GET /__ilha/loader.
@ilha/router/server-island-registry setFrameGuard(), setLoaderGuard(), setFrameAuth() — gate frame requests.

Quick start

Client-side SPA

import { router } from "@ilha/router";
import {
  HomePage,
  AboutPage,
  UserPage,
  NotFound,
} from "./pages";

router()
  .route("/", HomePage)
  .route("/about", AboutPage)
  .route("/user/:id", UserPage)
  .route("/**", NotFound)
  .mount("#app");

Server-side rendering

SSR is built into the SPA router — no separate server entry or render call. Add the SSR middleware and mark what runs on the server:

// vite.config.ts
import pages from "@ilha/router/vite";
import oxide from "oxidejs/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [
    oxide({ middleware: ["@ilha/router/ssr"] }),
    pages(),
  ],
});

Selective: move a component into a *.server.ts(x) file, import it, and use it like any other element. Its markup renders on the server and stays live through frames:

// src/pages/index.tsx
import { TaskList } from "$lib/tasks.server";

export default ilha.render(() => <TaskList />);

Whole pages: rename src/pages/about.tsx to src/pages/about.server.tsx and the entire route renders server-side.

Details: Server islands, Server pages.

Where to go next

Topic Page
Routes, navigation, route context Routes and navigation
Loaders and data fetching Loaders
File-system routing with the plugin File-system routing
SSR and manual rendering Server rendering
Server islands and server pages Server islands
Guards, origins, and security Middleware and security
Production deployment Deployment
Package symbol reference Router reference

Was this page helpful?