Skip to content

Instantly share code, notes, and snippets.

@RedHatter
Created December 4, 2020 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RedHatter/902d76e3b930be0430726868ccc670ca to your computer and use it in GitHub Desktop.
Save RedHatter/902d76e3b930be0430726868ccc670ca to your computer and use it in GitHub Desktop.
Single file router for svelte.
import { writable } from 'svelte/store'
const location = writable(window.location.pathname)
export default location
export let noMatch = writable(true)
location.subscribe(_ => noMatch.set(true))
window.addEventListener('popstate', e => location.set(window.location.pathname))
let hasPrevious = false
export function navigate(_path, replace = false) {
hasPrevious = true
const fn = replace ? 'replaceState' : 'pushState'
history[fn](null, '', _path)
location.set(window.location.pathname)
}
export function back() {
if (hasPrevious) history.back()
else navigate(window.location.pathname.replace(/[^/]+\/?$/, ''))
}
<script>
import UrlPattern from 'url-pattern'
import location, { navigate, noMatch } from './location.js'
export let path
export let component = undefined
export let redirect = undefined
$: pattern = new UrlPattern(path)
$: router = {
params: pattern.match($location),
path: $location,
}
$: {
if (router.params !== null) {
$noMatch = false
if (redirect) navigate(redirect, true)
}
}
</script>
{#if router.params !== null}
{#if component}
<svelte:component this={component} {router} {...$$restProps} />
{:else}
<slot {router} />
{/if}
{/if}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment