@tkhs0813/svelte-router
v0.0.1
Published
A lightweight routing library for Svelte 5 powered by the browser's [Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api).
Downloads
52
Maintainers
Readme
@tkhs0813/svelte-router
A lightweight routing library for Svelte 5 powered by the browser's Navigation API.
Features
- Navigation API native — A single
navigateevent handles all navigations instead ofpushState/popstate - Svelte 5 runes — Reactive router state with
$state/$derived - URLPattern based — Route matching with the browser-standard
URLPatternAPI - Minimal API — 2 components (
Router,Outlet) + a few helper functions - No click handlers needed — Navigation API automatically intercepts
<a>tag clicks
[!NOTE] The Navigation API is supported in Chromium-based browsers (Chrome, Edge, Opera). Firefox and Safari are not yet supported.
Install
npm install @tkhs0813/svelte-routerBasic Usage
Route Definitions and Router Setup
<!-- App.svelte -->
<script>
import { Router, Outlet } from '@tkhs0813/svelte-router';
import Home from './Home.svelte';
import About from './About.svelte';
import UserProfile from './UserProfile.svelte';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/users/:id', component: UserProfile }
];
</script>
<Router {routes}>
<Nav />
<main>
<Outlet />
</main>
</Router>Navigation Links
Use plain <a> tags. The Navigation API automatically intercepts clicks and converts them to SPA transitions.
Active state can be determined using router.url from getRouter(). Since router.url is a SvelteURL, properties like .pathname are reactive.
<!-- Nav.svelte -->
<script>
import { getRouter } from '@tkhs0813/svelte-router';
const router = getRouter();
</script>
<nav>
<a href="/" class:active={router.url.pathname === '/'}>Home</a>
<a href="/about" class:active={router.url.pathname === '/about'}>About</a>
<a href="/users" class:active={router.url.pathname.startsWith('/users')}>Users</a>
</nav>
<style>
a {
color: gray;
}
a.active {
color: blue;
font-weight: bold;
}
</style>Receiving Parameters in Route Components
Path parameters are passed as props.
<!-- UserProfile.svelte -->
<script>
let { id }: { id: string } = $props();
</script>
<h1>User {id}</h1>Programmatic Navigation
<script>
import { navigate, back, forward } from '@tkhs0813/svelte-router';
</script>
<button onclick={() => navigate('/about')}>Go to About</button>
<button onclick={() => navigate('/home', { replace: true })}>Replace with Home</button>
<button onclick={() => back()}>Back</button>
<button onclick={() => forward()}>Forward</button>Accessing Router State
<script>
import { getRouter } from '@tkhs0813/svelte-router';
const router = getRouter();
</script>
<p>Current path: {router.url.pathname}</p><p>Params: {JSON.stringify(router.current?.params)}</p>API
Components
<Router>
Initializes the router and provides router state to child components via context.
<Router {routes}>
<!-- children -->
</Router>| Prop | Type | Description |
| -------- | ------------------- | -------------------------- |
| routes | RouteDefinition[] | Array of route definitions |
<Outlet>
Renders the component matched by the current URL. Displays the fallback snippet if no route matches.
<Outlet>
{#snippet fallback()}
<p>404 - Page not found</p>
{/snippet}
</Outlet>Functions
navigate(url, options?)
Navigates to the specified URL.
navigate('/users/42');
navigate('/home', { replace: true });
navigate('/page', { state: { scrollY: 100 } });| Option | Type | Description |
| --------- | --------- | --------------------------------------------------------- |
| replace | boolean | Replace the current history entry instead of pushing |
| state | unknown | State stored via Navigation API (persists across reloads) |
| info | unknown | Transient metadata (not persisted in history) |
back() / forward()
Navigate back or forward in browser history.
getRouter()
Returns the router state object via Svelte context. Must be called inside a descendant of <Router>.
Properties:
| Property | Type | Description |
| ------------ | -------------------- | ------------------------------ |
| current | RouteMatch \| null | Currently matched route |
| url | URL (SvelteURL) | Current URL (reactive) |
| navigating | boolean | Whether a navigation is active |
Methods:
| Method | Description |
| -------------- | ------------------------------------------------------------ |
| addGuard(fn) | Register a navigation guard. Returns an unsubscribe function |
Types
interface RouteDefinition {
path: string; // URLPattern pathname (e.g. '/users/:id')
component: Component; // Svelte component
meta?: Record<string, unknown>; // Arbitrary metadata
}
interface RouteMatch {
route: RouteDefinition;
params: Record<string, string>;
url: URL;
}
interface NavigateOptions {
replace?: boolean;
state?: unknown;
info?: unknown;
}Path Patterns
Route paths use URLPattern pathname syntax.
const routes = [
{ path: '/', component: Home }, // Exact match
{ path: '/users/:id', component: User }, // Named parameter
{ path: '/files/*', component: FileViewer } // Wildcard
];Routes are matched in definition order. The first matching route is used.
