svelte-store-router
v2.0.10
Published
Store-based router for Svelte
Downloads
46
Maintainers
Readme
Store-based router for Svelte | Demo
Inspired by the svelte-pathfinder by PaulMaly
A completely different approach of routing. State-based router suggests that routing is just another global state and History API changes are just an optional side-effects of this state.
How it works (russian language)
Features
- Just another global state;
- It doesn't impose any restrictions on how to apply this state to the application;
- Manipulate different parts of a state (
path
/query
/fragment
) separately; - Automatic parsing of the
query
andfragment
parameters; - Components for
path
matching and parameters extracting (using regexparam); - Configurable delay of
History
changing; - Converting
query
andfragment
string values to JavaScript types; - Cleaning
query
andfragment
from empty values like anull
/undefined
/''
; - Automatically handling
<a>
navigation what allow updating the route state without reloading the page; - Works fine with SSR.
Install
npm i svelte-store-router --save-dev
Usage
Create a route store in your stores.js
:
import { createRouteStore } from 'svelte-store-router'
export const route = createRouteStore({
delay: 300,
queryClean: true,
fragmentClean: true
})
Now you can access it as usual store.
<script>
import { route } from './stores.js'
</script>
Full route: {$route}
Path: {$route.path}
Query: {$route.query}
Fragment: {$route.fragment}
You can change it.
<button on:click={() => $route.path = '/'}>home page</button>
<button on:click={() => $route.path = '/users'}>user list</button>
<button on:click={() => $route.query.sort = 'name'}>sort by name</button>
<button on:click={() => $route.query.team = 'svelte'}>filter by team</button>
<button on:click={() => $route.fragment.modal = true}>open modal window</button>
<button on:click={() => $route.fragment.scroll = 5}>skip first 50 users</button>
You can bind store values.
<textarea placeholder="fragment.search" bind:value={$route.fragment.search}/>
You can navigate to the full path you want by assigning a string value to the store or by calling the store's goto
function (without $). Don't forget that the route must be relative to the base path. So calling goto('https://google.com')
with base: '/test'
redirects you to /test/https://google.com
.
<button on:click={() => $route = '/users?orderBy=karma&limit=10'}>show top 10 users</button>
<button on:click={() => route.goto('/users?orderBy=karma&limit=10')}>show top 10 users</button>
You can match path pattern and parametrize it (regexparam).
<script>
import { Match } from 'svelte-store-router'
import { route } from './stores.js'
</script>
<Match route={$route} pattern="/users">
User list
</Match>
<Match route={$route} pattern="/users/:id" let:params={{ id }}>
User {id} profile
</Match>
You can show only first matching path.
<script>
import { Match, Matcher } from 'svelte-store-router'
import { route } from './stores.js'
</script>
<Matcher>
<Match route={$route} pattern="/users">
User list
</Match>
<Match route={$route} pattern="/users/:id" let:params={{ id }}>
User {id} profile
</Match>
<Match route={$route}>
Page not found
</Match>
<Match route={$route}>
This content will never be displayed, because
the previous <Match> handle all possible routes
</Match>
</Matcher>
You can use nested match components using the loose
parameter.
<script>
import { Match, Matcher } from 'svelte-store-router'
import { route } from './stores.js'
</script>
<Matcher>
<Match route={$route} pattern="/users" loose>
Begin of users template
<Matcher>
<Match route={$route} pattern="/users">
Users list
</Match>
<Match route={$route} pattern="/users/:id" let:params={{ id }}>
User {id} profile
</Match>
</Matcher>
End of users template
</Match>
<Match route={$route}>
Page not found
</Match>
</Matcher>
Or you can do it all above manually using match
function instead of components.
<script>
import { match } from 'svelte-store-router'
import { route } from './stores'
let params
</script>
<!--
It is recommended to first check if the route matches the base path of application by
calling `match($route)`. Not necessary if the application will always be in the root path.
-->
{#if match($route)}
{#if match($route, '/users', true)}
Begin of users template
{#if params = match($route, '/users/:id')}
User {params.id}
{:else if params = match($route, '/users/:id/friends')}
User {params.id} friends
{/if}
End of users template
{:else}
Page not found
{/if}
{/if}
Options
base [String]
Base path of application. Routes and links which not match under this path will not be handled. ''
by default.
delay [Number]
Sets delay in milliseconds before history.pushstate
was called. This prevents a large number of items from appearing in History state. For example, it could be useful when the parameter of query
or fragment
is binded with the search
input field. 0
by default.
queryParse, fragmentParse [Boolean]
Enables query
and fragment
string to objects conversion. true
by default.
queryTyped, fragmentTyped [Boolean]
Converts query and fragment string values to JavaScript types. true
by default. For example strings will be converted from -> to:
"1" -> 1
"0.123" -> 0.123
"true" -> true
"null" -> null
"undefined" -> undefined
"01234" -> 1234
"a1234" -> "a1234"
queryClean, fragmentClean [Boolean]
Clean query and fragment from empty (null
/ undefined
/ ""
) values. Might be useful to avoid /path?page=undefined&search=
. false
by default.
queryShortBoolean, fragmentShortBoolean [Boolean]
Automatically shortens the parameter string for boolean values, e.g. a=true&b=false&c=true
into a&c
. So for parameters with true
only the parameter name will be shown, and with false
they will be hidden completely. false
by default.
sideEffect [Boolean]
Controls side effect of route changing which push items to History. true
by default in browser, always false
on server side.
handleNavigation [Boolean / String]
Toggles a navigation handler that automatically intercepts <a>
clicks, updating the route state without reloading the page. Adding a rel="external"
attribute to a <a>
will trigger a usual browser navigation when the link is clicked. In addition to boolean, can contain a string with CSS selectors (e.g. ".foo, #bar, form"
) for elements only within which <a>
clicks should be handled. true
by default.
autoClearParams [Boolean]
This option toggles automatically clear the query
and fragment
when the path
is changed. false
by default.