Light & reactive client-side router for Svelte
Announcement of svelte-micro v3
npm i svelte-micro
<script>
import { Route, Link, linkHandle } from "svelte-micro"
</script>
<!-- Root component path always have to be equal to '/' -->
<Route>
<!-- Always will be shown -->
<nav use:linkHandle>
<a href="/">Home</a>
<a href="/portfolio">Portfolio</a>
<a href="/about-us/story">Our story</a>
<a href="https://github.com/ayndqy/svelte-micro">Github</a>
</nav>
<!-- Will be shown only when $path is equal to '/' -->
<Route path="/">
<h1>Home page</h1>
<p>Make yourself at home.</p>
</Route>
<Route path="/portfolio">
<h1>Portfolio</h1>
<!-- Will be shown only when $path is equal to '/portfolio' -->
<Route path="/">
<h2>Portfolio main page</h2>
<Link href="/portfolio/sites">Sites</Link>
<Link href="/portfolio/apps">Apps</Link>
</Route>
<Route path="/sites">
<h2>Sites</h2>
<Link href="/portfolio">Back to portfolio main page</Link>
</Route>
<Route path="/apps">
<h2>Apps</h2>
<Link href="/portfolio">Back to portfolio main page</Link>
</Route>
<Route fallback>
<h2>The route is not found in /portfolio</h2>
<Link href="/portfolio">Back to portfolio main page</Link>
</Route>
</Route>
<Route path="/about-us/story">
<h1>Our story</h1>
</Route>
<Route fallback>
<h1>The route is not found</h1>
<Link href="/">Back to home</Link>
</Route>
</Route>
This code shows the capabilities of the svelte-micro
routing system.
Spend a minute analyzing this example to understand the approach.
For advanced examples see the Tips section.
Entity | Related imports |
---|---|
router object |
import { router, type Router } from 'svelte-micro' |
options store |
import { options, type OptionsStore, type Options } from 'svelte-micro' |
path store |
import { path, type PathStore, type Path } from 'svelte-micro' |
query store |
import { query, type QueryStore, type Query } from 'svelte-micro' |
hash store |
import { hash, type HashStore, type Hash } from 'svelte-micro' |
Route component |
import { Route } from 'svelte-micro' |
Link component |
import { Link } from 'svelte-micro' |
linkHandle action |
import { linkHandle, type LinkHandle } from 'svelte-micro' |
getPathSegments function |
import { getPathSegments, type GetPathSegments } from 'svelte-micro' |
type Router = {
go: (delta?: number) => void
push: (url?: string | URL | null, state?: any) => void
replace: (url?: string | URL | null, state?: any) => void
}
The router
object is an object whose methods allow to manipulate history.
-
router.go
Move ondelta
steps through the history. -
router.push
Push newurl
andstate
to the history. -
router.replace
Replace currenturl
andstate
in the history.
type OptionsStore = {
subscribe: import('svelte/store').Readable<Options>['subscribe']
set: (changedOptions: Partial<Options>) => void
}
type Options = {
mode: 'window' | 'hash'
basePath: null | string
}
The options
store provides subscribe
and set
methods to access and modify router options.
-
$options.mode
Default:'window'
Set themode
for the router. -
$options.basePath
Default:null
Set thebasePath
for the router.
If abasePath
value is not found at the beginning of$path
, the router will continue to operate properly, ignoring thebasePath
option for this state of$path
. Be aware that ifmode
is set to'hash'
, the router will try to find thebasePath
value in the hash location fragment, since the hash location fragment is already separated from the path location fragment.
type Path = string
type PathStore = import('svelte/store').Readable<Path>
The store which contains current path.
type Query = string
type QueryStore = import('svelte/store').Readable<Query>
The store which contains current query.
type Hash = string
type HashStore = import('svelte/store').Readable<Hash>
The store which contains current hash.
<!--
props: { fallback: boolean; path: string; };
slots: { default: {}; };
-->
<Route fallback={false} path="/"> <slot /> </Route>
The Route
component defines a route. The props of Route
are reactive. A nested Route
component works in context of its parental Route
component, so you don't need to define its full path
.
-
fallback
Default:{false}
The property which defines if the route is fallback. A fallback route is active when there is no active routes on its depth. -
path
Default:'/'
The property which defines route path.path
must start from'/'
.
The top-level (root) Route
must have path
equal to '/'
and fallback
equal to false
.
These values are set by default, so you can leave them unchanged (see Example section).
<!--
props: { href: string; [x: string]: any; };
slots: { default: {}; };
-->
<Link href="/" {...restProps}> <slot /> </Link>
The <Link />
component is built on top of linkHandle
and should be used for the internal application navigation.
It automatically prevents the window from refreshing.
-
href
Default:'/'
The property which defines link href. -
{...restProps}
Any other property is attached on the innera
element.
If the basePath
option isn't set to null
, the <Link />
component will append the basePath
value to the href
attribute.
If the mode
option is set to "hash"
, the <Link />
component will append a #
to the beginning of the href
attribute.
type LinkHandle = import('svelte/action').Action<HTMLElement>
The linkHandle
action prevents window from refreshing when the click event occurs on a handled a[href]
element.
linkHandle
can be applied on a parental element to handle nested a[href]
elements.
linkHandle
ignores an a[href]
element if:
a[href]
hasdata-handle-ignore
attributea[href]
hastarget
attribute which isn't equal to'_self'
a[href]
has external href (new URL(href).origin !== document.location.origin
)(event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) === true
during the click event
export type GetPathSegments = (path: string) => string[]
The getPathSegments
function divides path
into segments.
For example: getPathSegments('/about-us/story') => ['/about-us', '/story']
.
<script>
import { path, query, hash } from 'svelte-micro'
// For example current location equals to '/somepath?text=Hello#modal'
// $path === '/somepath'
// $query === '?text=Hello'
// $hash === '#modal'
$: text = new URLSearchParams($query)?.get('text') ?? 'Fallback value'
</script>
<!-- Query usage example -->
{text}
<!-- Hash usage example -->
{#if $hash === '#modal'}
<div class="modal">Hello from modal!</div>
{/if}
import { path } from 'svelte-micro'
// Disable browser scroll behavior control
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual'
}
// On path change reset scroll position
path.subscribe(() => window.scrollTo(0, 0))
By default svelte-micro
doesn't control scroll behavior, but it's easy to do on your own.
<script>
import { router, Route } from 'svelte-micro'
</script>
<Route>
<Route path="/redirect">
{router.replace('/redirect-target')}
</Route>
<Route path="/redirect-target">
<h1>You have been redirected</h1>
</Route>
</Route>
<script>
import { Route } from 'svelte-micro'
let isUserAuthenticated = false
const toggleAuth = () => (isUserAuthenticated = !isUserAuthenticated)
</script>
<Route>
<Route path="/auth">
<button on:click={toggleAuth}>{isUserAuthenticated ? "Log out" : "Log in"}</button>
</Route>
{#if isUserAuthenticated}
<Route path="/profile">
<h1>Welcome!</h1>
<button on:click={toggleAuth}>Log out</button>
</Route>
{/if}
</Route>