Skip to content

Instantly share code, notes, and snippets.

@johanalkstal
Last active April 29, 2024 03:12
Show Gist options
  • Save johanalkstal/844a4ef899d4b493583a164ad2bdf28e to your computer and use it in GitHub Desktop.
Save johanalkstal/844a4ef899d4b493583a164ad2bdf28e to your computer and use it in GitHub Desktop.
Basic Svelte Store Routing
/**
* Basic example of routerless store based routing.
* To understand what is going on check out
* https://svelte.dev/tutorial/writable-stores
* https://www.npmjs.com/package/feather-route-matcher
*/
// stores.js
import { writable } from "svelte/store"
export const route = writable({
page: null,
params: null,
url: "",
})
// router.js
import createMatcher from "feather-route-matcher"
import { route } from "./stores"
export function setupRouter(routesMap) {
const routeMatcher = createMatcher(routesMap)
const updateStore = url => route.set(routeMatcher(url))
window.addEventListener("popstate", () =>
updateStore(window.location.pathname)
)
window.addEventListener("click", event => {
if (isLinkClick(event)) {
event.preventDefault()
updateStore(event.target.attributes.href.value)
}
})
route.subscribe(onRouteChange)
updateStore(window.location.pathname)
}
function isLinkClick(event) {
if (event.metaKey || event.ctrlKey || event.shiftKey) {
return false
}
if (event.defaultPrevented) {
return false
}
const { target } = event
if (
target.hasAttribute("download") ||
target.getAttribute("rel") === "external"
) {
return false
}
const { value: href } = target.attributes.href
if (href && href.indexOf("mailto:") > -1) {
return false
}
return true
}
function onRouteChange({ url }) {
if (window.location.pathname !== url) {
window.history.pushState(null, "", url)
document.body.scrollTop = 0
}
}
// main.js
import App from "./App.svelte"
import { setupRouter } from "./router"
import Home from "./Home.svelte"
const app = new App({
target: document.body,
})
setupRouter({
"/": Home,
})
export default app
// App.svelte
<script>
import { route } from './stores'
$: Page = $route.page
</script>
<svelte:component this={Page} {...$route}/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment