@magnet-js/router
v0.1.2
Published
Signal-based routing for Magnet applications.
Readme
@magnet/router
Signal-based routing for Magnet applications.
@magnet/router provides a minimal, composable routing core built on signals.
Routes are plain functions evaluated in registration order; the first
non-undefined result wins. No JSX, no route objects, no outlets — just
functions and arrays.
Install
JSR
deno add jsr:@magnet/routernpm via JSR
npx jsr add @magnet/routernpm
npm install @magnet-js/routerUsage
Basic routing
import { router } from "@magnet/router";
import { tc39 } from "@magnet/signal";
const routes = [
(l: URL) => l.pathname === "/" ? "Home" : undefined,
(l: URL) => l.pathname === "/about" ? "About" : undefined,
];
const r = router(tc39)(routes)(location);Path parameters
import { match, router } from "@magnet/router";
const routes = [
(l: URL) => {
const params = match(l.pathname, "/users/:id");
return params ? `User ${params.id}` : undefined;
},
];Search parameters
import { query, SearchTransform } from "@magnet/router";
const params = query({ page: SearchTransform.First })(location.search);
// ?page=1&page=2 → { page: "1" }Guards
Guards wrap a route handler and block it when a check fails. The check can read any external state, not just the location:
import { guard, router } from "@magnet/router";
import { tc39 } from "@magnet/signal";
const user = tc39.state<string | null>(null);
const authenticated = guard(() => user.get() !== null);
const routes = [
(l: URL) => l.pathname === "/login" ? "Login" : undefined,
authenticated((l: URL) => l.pathname === "/profile" ? "Profile" : undefined),
];When user is null, the /profile route falls through to the next registered
route (or the fallback).
Browser history
import { historian } from "@magnet/router";
const h = historian(tc39, window, {
restoreScroll: true,
focusTarget: "main",
})();Async routes
import { lazy } from "@magnet/common";
import { router } from "@magnet/router";
const routes = [
(l: URL) =>
l.pathname === "/heavy"
? lazy(tc39, () => import("./heavy.ts"), "Loading…")
: undefined,
];Accessibility announcer
import { announcer } from "@magnet/router";
import { magnet } from "@magnet/ui";
const m = magnet({ window, ...tc39 });
const el = announcer(m, location, (l) => `Navigated to ${l.pathname}`);Public API
router— creates a computed router signal from a route array and location.historian— creates a history adapter for browser or server.match— parses path patterns with:paramand*wildcards.query— parses URL search strings with per-key transformers.guard— wraps a route handler with a location check.announcer— creates an ARIA live region for screen reader announcements.Route/Router— route handler and router signal types.MagnetHistory/MagnetLocation— history adapter and location types.Historian/HistorianOptions— history factory and options.LocationTransformer— custom location shape transformer.SearchTransform— enum for common search value combinations.
License
MIT © 2026 Fernando G. Vilar.
