@zoijs/router
A tiny client-side router for single-page apps. Routes are a plain object; links are plain anchors.
npm install @zoijs/core @zoijs/routerExample#
import { html, mount } from "@zoijs/core";
import { createRouter } from "@zoijs/router";
const router = createRouter({
"/": Home,
"/about": About,
"/users/:id": (params) => html`<h1>User ${params.id}</h1>`,
"*": () => html`<h1>Not Found</h1>`,
});
function App() {
return html`
<nav>${router.link("/", "Home")} ${router.link("/about", "About")}</nav>
${router.view()}
`;
}
mount(App, "#app");A route is pattern: component. A component is a function that returns an html template and receives the matched params.
API#
| Member | What it does |
|---|---|
createRouter(routes, { base }) | Build a router from a { pattern: component } map |
router.view() | Render the current page — place it once |
router.link(path, text) | An <a> that navigates without a reload |
router.go(path) | Navigate from code |
router.path() | The current path (reactive) |
router.query() | The query string as an object (reactive) |
Patterns support static segments, dynamic :params, and a "*" not-found route. Static routes win over param routes. The active link gets aria-current="page" automatically.
Hosting under a sub-path#
If your app lives under a sub-path, pass a base so route patterns stay clean:
createRouter(routes, { base: "/app" });This very site uses the router. A hard refresh of a deep link needs a server fallback — see Deployment.
Known limitations#
- History mode only (deep-link refreshes need a server SPA fallback).
- No nested-outlet system, route guards, or loaders — by design.
- No SSR.