# Advanced topics
## Architecture
The router uses a **pipeline architecture** for clean separation of concerns:
```mermaid
flowchart TD
Start([User Navigation]) --> Effect[🔄 Reactive Effect Reads location state]
Effect --> Snapshot[📸 Capture Current Route for Referrer Tracking]
Snapshot --> Pipeline[⚙️ Async Pipeline No reactive tracking]
Pipeline --> Stage1[1️⃣ Find Matching Route Pattern matching with regexparam]
Stage1 --> Stage2[2️⃣ Load Component Async import & race protection]
Stage2 --> Stage3[3️⃣ Execute Guards Permissions & conditions]
Stage3 --> Stage4[4️⃣ Inject Referrer Track previous route]
Stage4 --> Stage5[5️⃣ Update Metadata Breadcrumbs & route data]
Stage5 --> Commit[💾 Commit to Reactive State Single write operation]
Commit --> Render[🎨 Svelte Renders Component with props]
Stage3 -->|Guard Failed| Unauthorized[❌ Unauthorized Redirect or 401]
Stage1 -->|No Match| NotFound[🔍 404 Not Found Catch-all route]
style Pipeline fill:#e3f2fd
style Commit fill:#c8e6c9
style Effect fill:#fff9c4
style Render fill:#f3e5f5
style Unauthorized fill:#ffccbc
style NotFound fill:#ffccbc
```
### Key benefits
- **No `untrack()` calls needed**: pipeline runs outside reactive context
- **Race condition safety**: each navigation has a unique ID to prevent stale updates
- **Single write point**: all state updates happen in one place (`commitToReactiveState`)
- **Testable**: pure functions for each pipeline stage
- **Extensible**: easy to add new stages or modify existing ones
## Svelte 5 runes (not stores)
This router uses Svelte 5 runes throughout, not Svelte stores.
### 1. Stores are now functions
In the Svelte 5 version, location stores are accessed as functions instead of Svelte stores:
```svelte
Current location: {location()}
Querystring: {querystring()}
Params: {JSON.stringify(routeParams())}
```
### 2. Event handlers use props instead of `on:` directives
```svelte
```
### 3. Internal implementation uses runes
The router uses:
- `$state` for reactive state management
- `$props` for component props
- `$effect` for side effects (location tracking, scroll restoration)
- `$derived` for computed values
### What NOT to do
- ❌ Don't use Svelte stores (`writable()`, `readable()`, `derived()`)
- ❌ Don't use `$:` reactive declarations (use `$derived()` instead)
- ❌ Don't use `export let` for props (use `let { prop } = $props()`)
- ❌ Don't use `.subscribe()` or `$store` syntax
- ❌ Don't use manual `push(referrer.location)` for "Go Back" (use `goBack()` helper for scroll restoration)
## Scroll restoration
```svelte
```
Uses `history.scrollRestoration = 'manual'` and stores scroll positions in history state. The `goBack()` helper automatically restores scroll position when navigating to referrer. Manual `push()` does NOT restore scroll.
## Nested routers
```svelte
Hello!
```
## Event handling
```svelte
console.log('Loading:', e.detail)}
onRouteLoaded={(e) => console.log('Loaded:', e.detail)}
onConditionsFailed={(e) => console.log('Failed:', e.detail)}
onNotFound={(e) => console.log('Not found:', e.detail)}
/>
```
**Event payloads (`e.detail`):**
| Event | Payload shape | Fires when |
|---|---|---|
| `onRouteLoading` | `{ route, location, relativeLocation, querystring, params }` | Before guards/conditions run for a matched route |
| `onRouteLoaded` | `{ route, location, relativeLocation, querystring, params, component?, name?, routeContext?, zones? }` | After the matched component (and any async children) successfully mounts. `zones` is set for multi-zone routes; `component`/`name`/`routeContext` for single-component routes |
| `onConditionsFailed` | `{ route, location, relativeLocation, querystring, params }` | A condition in `wrap({ conditions })` returned `false`. The slot is now empty — handle the redirect here or inside the condition itself |
| `onNotFound` | `{ location, relativeLocation, querystring }` | No route matched, *or* the `'*'` catch-all matched (it fires for both, so consumers can always log 404s) |
**`location` vs `relativeLocation`:**
- `location` is the **full app URL** as the browser sees it (e.g. `/test/embed/missing`). Use this for logging, analytics, or re-navigating with `push()` (which always takes app-wide paths).
- `relativeLocation` is the URL **after the Router's `prefix` has been stripped** (e.g. `/missing` for a ``). Use this when you're reasoning about what *this* Router instance saw — it matches how routes inside the Router were defined.
- For a root Router with no `prefix`, the two fields are identical.
## Quick reference
### All available imports
```javascript
// Core router
import Router from '@keenmate/svelte-spa-router'
// Navigation utilities
import { push, replace, pop, goBack, location, querystring, routeParams, navigationContext } from '@keenmate/svelte-spa-router'
// Named routes (for use with push/replace/link)
import { registerRoutes, buildUrl, defineRoutes } from '@keenmate/svelte-spa-router/routes'
// Route creation (recommended - no wrap() needed!)
import { createRoute, createRouteDefinition } from '@keenmate/svelte-spa-router/wrap'
// Route wrapping (advanced - for manual wrapping)
import { wrap } from '@keenmate/svelte-spa-router/wrap'
// Tree/nested route structure (alternative to flat routes)
import { createHierarchy } from '@keenmate/svelte-spa-router/helpers/hierarchy'
// Active link highlighting
import active from '@keenmate/svelte-spa-router/active'
// Configuration
import { setHashRoutingEnabled, setBasePath, setParamReplacementPlaceholder, setHierarchicalRoutesEnabled, setIncludeReferrer } from '@keenmate/svelte-spa-router'
// Querystring helpers (shared reactive state)
import { configureQuerystring, query } from '@keenmate/svelte-spa-router/helpers/querystring'
// Querystring helpers (individual functions)
import {
parseQuerystring,
stringifyQuerystring,
updateQuerystring
} from '@keenmate/svelte-spa-router/helpers/querystring-helpers'
// Filter helpers
import {
configureFilters,
filters,
updateFilters
} from '@keenmate/svelte-spa-router/helpers/filters'
// Permission system (recommended - no wrap() needed!)
import {
configurePermissions,
createProtectedRoute,
hasPermission
} from '@keenmate/svelte-spa-router/helpers/permissions'
// Permission system (advanced - for manual wrapping)
import {
createPermissionCondition,
createProtectedRouteDefinition
} from '@keenmate/svelte-spa-router/helpers/permissions'
// Navigation guards
import {
registerBeforeLeave,
unregisterBeforeLeave,
NavigationCancelledError,
createDirtyCheckGuard
} from '@keenmate/svelte-spa-router/helpers/navigation-guard'
// Route metadata & loading control
import {
showLoading,
hideLoading,
routeIsLoading,
updateTitle,
updateBreadcrumb,
updateRouteMetadata,
routeTitle,
routeBreadcrumbs,
routeContext
} from '@keenmate/svelte-spa-router/helpers/route-metadata'
```
### Common patterns
```svelte