History base router for Svelte 3 SPA (Single Page Application).
- History-base routing
- path matching and path variable capturing by regular expression
- resolver (for dynamic routing, code-splitting, data preloading, etc...)
- Hash-base routing
- Nested router
- SSR (Server Side Rendering)
$ npm install --save-dev svelte-spa-history-router
$ # or
$ yarn add svelte-spa-history-router
Import Router
and put into your main component (typically App.svelte).
For example:
# App.svelte
<script>
import { Router } from 'svelte-spa-history-router';
import Home from './Home.svelte';
import Article from './Article.svelte';
import NotFound from './NotFound.svelte';
const routes = [
{ path: '/', component: Home},
{ path: '/posts/(?<postId>.*)', component: Article},
{ path: '.*', component: NotFound},
];
</script>
<Router {routes}/>
-
Routes
require aroutes
parameter. -
routes
is a list of route objects. route object haspath
,component
, andresolver
properties.-
path
can be a regular expression.^
and$
are automatically added when matching. -
component
is a SvelteComponent. there are no specific requirements for component. -
resolver
is a function to determine component dynamically (optional).
-
-
Matching is simply performed in the order defined by
routes
.
routeParams
is a store to contain matched value to current route.
For example:
# Article.svelte
<script>
import { routeParams } from 'svelte-spa-history-router';
</script>
<div class="article">
postId: {$routeParams.postId}
</div>
To navigate another page, link
and push
are available.
-
link
used with aa
tag like below
import { link } from 'svelte-spa-history-router';
<a use:link href="/">Home</a>
-
push
used to navigate programatically
import { push } from 'svelte-spa-history-router';
<button on:click={ () => push('/') }>Go to Home</button>
Resolver is a mechanism to dynamically determine component and can be used in multiple use cases.
Example: code spliting (dynamic import)
<script>
import { Router } from 'svelte-spa-history-router';
const routes = [
{ path: '/', resolver: _ => import("Home.svelte") },
];
</script>
<Router {routes}/>
Example: dynamic routing and pass value to component props.
<script>
import { Router } from 'svelte-spa-history-router';
import Article from "./Article.svelte";
import NotFound from "./NotFound.svelte";
async function prefetchArticle(route) {
const article = await getArticle(route.params.postId);
if (article) {
// pass value to component props
route.props.article = article;
return Article;
} else {
return NotFound;
}
}
const routes = [
{ path: '/posts/(?<postId>.*)', resolver: prefetchArticle },
];
</script>
<Router {routes}/>
Example: guard
<script>
import { Router, redirect } from 'svelte-spa-history-router';
import Admin from "./Admin.svelte";
function adminGuard(route) {
if (!isAdmin($user)) {
return redirect("/");
}
return Admin;
}
const routes = [
{ path: '/', component: Home },
{ path: '/admin', resolver: adminGuard },
];
</script>
<Router {routes}/>
(Added in v2.0.0)
store to detect URL changes (including query string or hash)
<script>
import { currentURL } from "svelte-spa-history-router";
$: name = $currentURL.searchParams.get("name") || 'unknown';
</script>
<div>{ name }</div>
(Added in 2.1.0)
- Support types PR10
-
Support TypesAdd typecheck PR9
- Add
currentURL
store to detect URL changes PR6
- [Added] resolver
- [Removed] guard
- Fix bug with async guard function causing loop
- Add guard
- Fix import error
MIT License.
Generally, history-base router requires server-side routing so that user can open the direct link or reload.
For example, Nginx excerpt configuration is like bellow.
location / {
try_files $uri /index.html =404;
}
If you consider to use firebase hosting for your application, rewrite may be useful.
svelte-spa-history-router is inspired by svelte-spa-router and Svelte Router SPA.
If you don't need both history-base and regular expression support, I reccommend these powerful routers.