{"id":17677489,"url":"https://github.com/dvcol/svelte-simple-router","last_synced_at":"2025-08-21T15:31:41.499Z","repository":{"id":256263070,"uuid":"851850246","full_name":"dvcol/svelte-simple-router","owner":"dvcol","description":"Simple svelte 5 client side router.","archived":false,"fork":false,"pushed_at":"2024-10-24T17:51:34.000Z","size":733,"stargazers_count":27,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-24T22:17:33.115Z","etag":null,"topics":["client-side","library","router","spa","svelte","svelte-5"],"latest_commit_sha":null,"homepage":"https://dvcol.github.io/svelte-simple-router/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dvcol.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"paypal.me/dvcol/5"}},"created_at":"2024-09-03T19:56:45.000Z","updated_at":"2024-10-24T21:37:56.000Z","dependencies_parsed_at":"2024-10-26T03:39:17.345Z","dependency_job_id":null,"html_url":"https://github.com/dvcol/svelte-simple-router","commit_stats":null,"previous_names":["dvcol/svelte-simple-router"],"tags_count":14,"template":false,"template_full_name":"dvcol/typescript-lib-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvcol%2Fsvelte-simple-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvcol%2Fsvelte-simple-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvcol%2Fsvelte-simple-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvcol%2Fsvelte-simple-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dvcol","download_url":"https://codeload.github.com/dvcol/svelte-simple-router/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230520390,"owners_count":18238948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client-side","library","router","spa","svelte","svelte-5"],"created_at":"2024-10-24T07:28:50.768Z","updated_at":"2025-08-21T15:31:41.481Z","avatar_url":"https://github.com/dvcol.png","language":"TypeScript","funding_links":["paypal.me/dvcol/5","https://paypal.me/dvcol/5"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eWelcome to \u003ci\u003eSvelte Simple Router\u003c/i\u003e\u003c/h1\u003e\n\u003ch3 align=\"center\"\u003eA simple and flexible SPA router for svelte 5\u003c/h3\u003e\n\n\u003cp\u003e\n  \u003cimg src=\"https://img.shields.io/badge/pnpm-%3E%3D8.0.0-blue.svg\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/node-%3E%3D20.0.0-blue.svg\" /\u003e\n  \u003ca href=\"https://github.com/dvcol/svelte-simple-router#readme\" target=\"_blank\"\u003e\n    \u003cimg alt=\"Documentation\" src=\"https://img.shields.io/badge/documentation-yes-brightgreen.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/dvcol/svelte-simple-router/graphs/commit-activity\" target=\"_blank\"\u003e\n    \u003cimg alt=\"Maintenance\" src=\"https://img.shields.io/badge/Maintained%3F-yes-green.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/dvcol/svelte-simple-router/blob/master/LICENSE\" target=\"_blank\"\u003e\n    \u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/github/license/dvcol/svelte-simple-router\" /\u003e\n  \u003c/a\u003e\n \u003ca href=\"https://paypal.me/dvcol/5\" target=\"_blank\"\u003e\n    \u003cimg alt=\"donate\" src=\"https://img.shields.io/badge/Donate%20€-PayPal-brightgreen.svg\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Description\n\nSvelte Simple Router is a native Single Page Application (SPA) router for Svelte 5, designed for seamless client-side navigation while leveraging Svelte's reactivity and transitions.\n\nIt supports both History API and hash routing, offering flexible URL management with robust path matching, query parameter handling, and dynamic interpolation. Packed with features like nested views, route guards, lazy loading, dynamic routing, and full integration with Svelte’s Transition API and the View Transitions API, it enables smooth and interactive navigation experiences.\n\nBuilt to be easy to use yet powerful, Svelte Simple Router is the perfect solution for developers looking to add routing to their Svelte applications without unnecessary complexity.\n\n## Prerequisites\n\nNote: Svelte Simple Router is a svelte 5 native library, and will not work with prior versions of svelte.\n\n- svelte \u003e= 5.0.0\n\n## Install\n\n```sh\npnpm add @dvcol/svelte-simple-router\n```\n\n## Getting Started\n\nThe minimal setup requires a `RouterView` component and a list of routes.\n\nThe `RouterView` component will render the component associated with the current route in place.\n\nYou can find a complete example in the [demo app](https://github.com/dvcol/svelte-simple-router/blob/main/demo/App.svelte), or [this playground](https://svelte.dev/playground/4dff6a053c024e729e203b5c37d9029c?version=5.25.10).\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import type { Route, RouterOptions } from '@dvcol/svelte-simple-router/models';\n\n  import { RouterView } from '@dvcol/svelte-simple-router/components';\n  import GoodbyeComponent from '~/components/goodbye/GoodbyeComponent.svelte';\n  import HelloComponent from '~/components/hello/HelloComponent.svelte';\n\n  const RouteName = {\n    Hello: 'hello',\n    Goodbye: 'goodbye',\n    Home: 'home',\n    Any: 'any',\n  } as const;\n\n  type RouteNames = (typeof RouteName)[keyof typeof RouteName];\n\n  const routes: Readonly\u003cRoute\u003cRouteNames\u003e[]\u003e = [\n    {\n      name: RouteName.Home,\n      path: '/',\n      redirect: {\n        name: RouteName.Hello,\n      },\n    },\n    {\n      name: RouteName.Hello,\n      path: `/${RouteName.Hello}`,\n      component: HelloComponent,\n    },\n    {\n      name: RouteName.Goodbye,\n      path: `/${RouteName.Goodbye}`,\n      component: GoodbyeComponent,\n    },\n    {\n      name: RouteName.Any,\n      path: '*',\n      redirect: {\n        name: RouteName.Hello,\n      },\n    },\n  ] as const;\n\n  const options: RouterOptions\u003cRouteNames\u003e = {\n    routes,\n  } as const;\n\n\u003c/script\u003e\n\n\u003cRouterView {options} /\u003e\n```\n\n## Advanced Usage\n\n- [Router Context](#router-context)\n- [Debuggers](#debuggers)\n- [Nested routes](#nested-routes)\n- [Router transition](#router-transition)\n  - [Svelte transition](#svelte-transition)\n  - [View Transition API](#view-transition-api)\n- [Dom actions](#dom-actions)\n  - [Link action](#link-action)\n  - [Links action](#links-action)\n  - [Active action](#active-action)\n- [Programmatic navigation](#programmatic-navigation)\n  - [Hooks](#hooks)\n  - [Router instance](#router-instance)\n  - [Outside component tree](#outside-component-tree)\n- [Dynamic routes](#dynamic-routes)\n- [Guards and listeners](#guards-and-listeners)\n  - [Navigation listeners](#navigation-listeners)\n  - [Loading Listeners](#loading-listeners)\n- [Lazy routing](#lazy-routing)\n- [Routes](#routes)\n- [Router](#router)\n\n### Router Context\n\nThe `RouterContext` component injects the router instance into the component tree.\n\nIt can be used to share a router instance between `RouterView` components without the need to pass it down as a prop.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { RouterContext } from '@dvcol/svelte-simple-router/components';\n\u003c/script\u003e\n\n\u003cRouterContext\u003e\n  \u003c!--  children  --\u003e\n\u003c/RouterContext\u003e\n```\n\n### Debuggers\n\nThe `RouterDebugger` and `RouteDugger` component will display the current route and router state.\n\nIt can be used to debug the router configuration and the current route.\n\nIt requires to be placed inside a `RouterView` or `RouterContext` component.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { RouterView } from '@dvcol/svelte-simple-router/components';\n  import { RouteDebugger, RouterDebugger } from '@dvcol/svelte-simple-router/components/debug';\n\u003c/script\u003e\n\n\u003cRouterView\u003e\n  \u003cRouterDebugger /\u003e\n  \u003cRouteDebugger /\u003e\n\u003c/RouterView\u003e\n```\n\n### Nested routes\n\nThe `RouterView` component can be nested under another `RouterView` or `RouterContext` component.\n\nNamed `RouterView` components can be used to render different components on the same route.\n\nEach `RouterView` grabs the router context from the nearest `RouterContext` or `RouterView` component.\n\nNote: Sibling `RouterView` or `RouterContext` components will instantiate a new router instance.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import type { Route, RouterOptions } from '@dvcol/svelte-simple-router/models';\n\n  import { RouterContext, RouterView } from '@dvcol/svelte-simple-router/components';\n  import ChildComponent from '~/components/goodbye/ChildComponent.svelte';\n  import ParentComponent from '~/components/hello/ParentComponent.svelte';\n\n  const RouteName = {\n    Parent: 'parent',\n    Child: 'child',\n  } as const;\n\n  type RouteNames = (typeof RouteName)[keyof typeof RouteName];\n\n  export const routes: Readonly\u003cRoute\u003cRouteNames\u003e[]\u003e = [\n    {\n      name: RouteName.Parent,\n      path: `/${RouteName.Parent}`,\n      component: ParentComponent,\n    },\n    {\n      name: RouteName.Nested,\n      path: `/${RouteName.Parent}/${RouteName.Child}`,\n      components: {\n        default: ParentComponent,\n        nested: ChildComponent,\n      },\n    },\n  ] as const;\n\n  export const options: RouterOptions\u003cRouteNames\u003e = {\n    routes,\n  } as const;\n\n\u003c/script\u003e\n\n\u003cRouterContext {options}\u003e\n  \u003cRouterView\u003e\n    \u003c!--  will render ParentComponent  --\u003e\n  \u003c/RouterView\u003e\n\n  \u003cRouterView name=\"nested\"\u003e\n    \u003c!--  will only render ChildComponent on /parent/child, and nothing on /parent --\u003e\n  \u003c/RouterView\u003e\n\u003c/RouterContext\u003e\n```\n\n### Router transition\n\n#### Svelte transition\n\nThe `RouterView` component can take a `transition` [prop](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L97-L122) to animate the route transition.\n\nIt wraps the route component in a div with optionals `in` and `out` transitions.\n\nA default fade/scale transition is provided, but you can pass your own [transitions](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L97-L122).\n\nNote: By default the first enter transition is ignored, you can change this behavior by setting the `skipFirst` option to `false`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { RouterView } from '@dvcol/svelte-simple-router/components';\n  import { transition } from '@dvcol/svelte-simple-router/utils';\n\n  ...\n\u003c/script\u003e\n\n\u003cRouterView {transition} {options} /\u003e\n```\n\n#### View Transition API\n\nIf you want to use the [view-transition API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) instead, you can pass a `viewTransitionName` key in the `transition` prop of the `RouterView` component.\n\nIf `viewTransitionName` is a string, it will be used as the `viewTransitionName`, otherwise a unique id will be generated `sr-container-\u003crouter-id\u003e-\u003cview-id\u003e`.\n\nThen, you can use one or a combination of lifecycle hooks like `onChange` or `onStart` to trigger transitions.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onChange, onError, onLoaded } from '@dvcol/svelte-simple-router/router';\n\n  let resolve: () =\u003e void;\n\n  const starTransition = () =\u003e {\n    const { promise: transition, resolve: end } = Promise.withResolvers\u003cvoid\u003e();\n    resolve = end;\n\n    const { promise: wait, resolve: start } = Promise.withResolvers\u003cvoid\u003e();\n    document.startViewTransition(async () =\u003e {\n      start();\n      await transition;\n    });\n    return wait;\n  };\n\n  onChange(async () =\u003e {\n    if (resolve) resolve();\n    return starTransition();\n  });\n\n  onError(() =\u003e resolve?.());\n  onLoaded(() =\u003e resolve?.());\n\u003c/script\u003e\n```\n\n### Dom actions\n\n#### Link action\n\nThe `link action` intercepts click events on dom elements and triggers a router navigation instead.\n\nThe link action will prevent the default behavior and use the router only if the following conditions are met:\n\n- The element is within a router context\n- The event is a left click or enter key\n- The event does not have a modifier key\n- The target is not an external link (for anchor elements)\n- The target is not a new tab or window (for anchor elements)\n\nAdditionally:\n\n- The action merge data-attributes with the options passed as argument.\n- Passed options have precedence over data-attributes.\n- If attribute expects a JSON object, it will be parsed.\n- If a name or path parameter are provided, they will be used to navigate and href will be ignored.\n- Name takes precedence over path.\n- If the host is not an anchor element, the role and tabindex attributes will be set.\n- If resolve: true is passed, the target route will be resolved and any lazy component will be loaded on hover/focus\n- If resolve: view-name is passed, only the target view will be resolved/loaded on hover/focus.\n\nNote: The action requires the router context to be present in the component tree.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { link } from '@dvcol/svelte-simple-router/router';\n\u003c/script\u003e\n\n\u003ca href=\"/path/:param?query=value\" use:link\u003esimple link\u003c/a\u003e\n\u003ca href='goodbye' name use:link\u003enamed link\u003c/a\u003e\n\u003ca href='/path/:param' data-query='{\"query\":\"value\"}' use:link\u003elink with query\u003c/a\u003e\n\u003ca href='/path/:param' use:link=\"{ params: { param: 'value' } }\"\u003elink with params\u003c/a\u003e\n\u003cdiv href='/path/:param' use:link=\"{ params: { param: 'value' } }\"\u003ediv link\u003c/div\u003e\n\u003cbutton href='/path/:param' use:link=\"{ params: { param: 'value' } }\"\u003ebutton link\u003c/button\u003e\n```\n\n#### Link attachment\n\nThe `link attachment` intercepts click events on dom elements and triggers a router navigation instead.\n\nSimilar to the `link action`, see the [link action](#link-action) for more information.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useLink } from '@dvcol/svelte-simple-router/attachment';\n\u003c/script\u003e\n\n\u003ca href=\"/path/:param?query=value\" {@attach useLink()}\u003esimple link\u003c/a\u003e\n\u003ca href='goodbye' name {@attach useLink()}\u003enamed link\u003c/a\u003e\n\u003ca href='/path/:param' data-query='{\"query\":\"value\"}' {@attach useLink()}\u003elink with query\u003c/a\u003e\n\u003ca href='/path/:param' {@attach useLink({ params: { param: 'value' } })}\u003elink with params\u003c/a\u003e\n\u003cdiv href='/path/:param' {@attach useLink({ params: { param: 'value' } })}\u003ediv link\u003c/div\u003e\n\u003cbutton href='/path/:param' {@attach useLink({ params: { param: 'value' } })}\u003ebutton link\u003c/button\u003e\n```\n\n#### Links action\n\nThe `links action` intercepts click events on dom elements and upwardly navigate the dom tree until it reaches a link element and triggers a router navigation instead.\n\nThe links action will recognize a parent node as a router link if it satisfies any of the following conditions:\n\n- The element is an anchor element\n- The element has a `data-router-link` attribute\n- The element satisfies the `apply` selector function passed as argument\n\nWhen a node is recognized as a router link, the action will behave as the `link` action (all restrictions apply).\n\nAdditionally:\n\n- The action requires either valid href or data-attributes to navigate.\n- Once the action reaches the host element or the `boundary` element (or selector function), it will stop evaluating the dom tree.\n\nNote: The action requires the router context to be present in the component tree.\nNote: Unlike use:link, use:links does not normalize link attributes (role, tabindex, href).\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { links } from '@dvcol/svelte-simple-router/router';\n\u003c/script\u003e\n\n\u003cdiv use:links\u003e\n  \u003cdiv\u003e\n    \u003ca href=\"/path/:param?query=value\"\u003esimple link\u003c/a\u003e\n  \u003c/div\u003e\n  \u003cdiv data-router-link data-name=\"Hello\"\u003e\n    \u003cspan\u003esimple span\u003c/span\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n#### Links attachment\n\nThe `links attachment` intercepts click events on dom elements and upwardly navigate the dom tree until it reaches a link element and triggers a router navigation instead.\n\nSimilar to the `links action`, see the [links action](#links-action) for more information.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useLinks } from '@dvcol/svelte-simple-router/attachment';\n\u003c/script\u003e\n\n\u003cdiv {@attach useLinks()}\u003e\n  \u003cdiv\u003e\n    \u003ca href=\"/path/:param?query=value\"\u003esimple link\u003c/a\u003e\n  \u003c/div\u003e\n  \u003cdiv data-router-link data-name=\"Hello\"\u003e\n    \u003cspan\u003esimple span\u003c/span\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n#### Active action\n\nThe `active action` adds an active state (class, style or attribute) to an element when the route matches.\n\nAdditionally:\n\n- If attached to an anchor element, it will attempt to match the href attribute.\n- If path or name options are provided, they will take precedence over the element attributes.\n- Name always takes precedence over path.\n- When the route un-matches, the original style will be restored.\n\nNote: The action requires the router context to be present in the component tree.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { active } from '@dvcol/svelte-simple-router/action';\n\u003c/script\u003e\n\n\u003ca href=\"/path\" use:active\u003esimple link\u003c/a\u003e\n\u003ca href=\"/path\" data-name=\"route-name\" use:active\u003enamed link\u003c/a\u003e\n\u003cbutton use:active=\"{ path: '/path' }\"\u003ebutton link\u003c/button\u003e\n\u003cdiv use:active=\"{ name: 'route-name' }\"\u003ediv link\u003c/div\u003e\n```\n#### Active attachment\n\nThe `active attachment` adds an active state (class, style or attribute) to an element when the route matches.\n\nSimilar to the `active` action, see the [active action](#active-action) for more information.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useActive } from '@dvcol/svelte-simple-router/attachment';\n\u003c/script\u003e\n\n\u003ca href=\"/path\" {@attach useActive()}\u003esimple link\u003c/a\u003e\n\u003ca href=\"/path\" data-name=\"route-name\" {@attach useActive()}\u003enamed link\u003c/a\u003e\n\u003cbutton {@attach useActive({ path: '/path' })}\u003ebutton link\u003c/button\u003e\n\u003cdiv {@attach useActive({ name: 'route-name' })}\u003ediv link\u003c/div\u003e\n```\n\n### Programmatic navigation\n\n#### Hooks\n\n- `hasRouter` \u0026 `useRouter` - Returns the router instance\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useRouter } from '@dvcol/svelte-simple-router/router';\n\n  const router = useRouter();\n\u003c/script\u003e\n```\n\n- `hasView` \u0026 `useView` - Returns the view instance\n\nMust be used within a `RouterView`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useView } from '@dvcol/svelte-simple-router/router';\n\n  const view = useView();\n\u003c/script\u003e\n```\n\n- `useRoute` - Returns the current `route`, `location` and the `routing`state\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useRoute } from '@dvcol/svelte-simple-router/router';\n\n  const { route, location, routing } = $derived(useRoute());\n\n  const reactiveRoute = $derived(route);\n  const reactiveLocation = $derived(location);\n  const reactiveRoutingState = $derived(routing);\n\n  const pathParams = $derived(location.params);\n  const queryParams = $derived(location.query);\n\u003c/script\u003e\n```\n\n- `useNavigate` - Returns utility function to start navigation logic.\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useNavigate } from '@dvcol/svelte-simple-router/router';\n\n  const { resolve, push, replace, back, forward, go } = useNavigate();\n\u003c/script\u003e\n```\n\n- `beforeEach` - Returns a onMount hook that register (and auto-clean) a listener that triggers before each navigation event\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { beforeEach } from '@dvcol/svelte-simple-router/router';\n\n  beforeEach((event) =\u003e {\n    console.info('before navigation', event);\n  });\n\u003c/script\u003e\n```\n\n- `onStart` - Returns a onMount hook that register (and auto-clean) a listener that triggers at the start of each navigation event\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onStart } from '@dvcol/svelte-simple-router/router';\n\n  onStart((event) =\u003e {\n    console.info('start of navigation', event);\n  });\n\u003c/script\u003e\n```\n\n- `onEnd` - Returns a onMount hook that register (and auto-clean) a listener that triggers at the end of each navigation event\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onEnd } from '@dvcol/svelte-simple-router/router';\n\n  onEnd((event) =\u003e {\n    console.info('end of navigation', event);\n  });\n\u003c/script\u003e\n```\n\n- `onChange` - Returns a onMount hook that register (and auto-clean) a listener that triggers at the start of a view change.\n\nMust be used within a `RouterView`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onChange } from '@dvcol/svelte-simple-router/router';\n\n  onChange((event) =\u003e {\n    console.info('start of view change', event);\n  });\n\u003c/script\u003e\n```\n\n- `onLoading` - Returns a onMount hook that register (and auto-clean) a listener that triggers when a view start loading an async component.\n\nMust be used within a `RouterView`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onLoading } from '@dvcol/svelte-simple-router/router';\n\n  onLoading((event) =\u003e {\n    console.info('loading view', event);\n  });\n\u003c/script\u003e\n```\n\n- `onLoaded` - Returns a onMount hook that register (and auto-clean) a listener that triggers when a view finish loading a component.\n\nMust be used within a `RouterView`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onLoaded } from '@dvcol/svelte-simple-router/router';\n\n  onLoaded((event) =\u003e {\n    console.info('view loaded', event);\n  });\n\u003c/script\u003e\n```\n\n- `onError` - Returns a onMount hook that register (and auto-clean) a listener that triggers when an error occurs during navigation or view change.\n\nMust be used within a `RouterView`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { NavigationEvent, onError, ViewChangeEvent } from '@dvcol/svelte-simple-router/router';\n\n  onError((err, event) =\u003e {\n    if (event instanceof NavigationEvent) {\n      console.error('Navigation Error', { err, event });\n    } else if (event instanceof ViewChangeEvent) {\n      console.error('View change error', { err, event });\n    } else {\n      console.error('Unknown Error', { err, event });\n    }\n  });\n\u003c/script\u003e\n```\n\n- `onViewError` - Returns a onMount hook that register (and auto-clean) a listener that triggers when an error occurs during view change.\n\nMust be used within a `RouterView`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onViewError } from '@dvcol/svelte-simple-router/router';\n\n  onViewError((err, event) =\u003e {\n    console.error('View change error', { err, event });\n  });\n\u003c/script\u003e\n```\n\n- `onRouterError` - Returns a onMount hook that register (and auto-clean) a listener that triggers when an error occurs during navigation.\n\nMust be used within a `RouterView` or `RouterContext`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onRouterError } from '@dvcol/svelte-simple-router/router';\n\n  onRouterError((err, event) =\u003e {\n    console.error('Navigation error', { err, event });\n  });\n\u003c/script\u003e\n```\n\n#### Router instance\n\nFor more complexe usage, you can grab the router instance from the context and call the `push` or `replace` methods.\n\nSee the [router model](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L482-L501) for more information.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { useRouter } from '@dvcol/svelte-simple-router/router';\n\n  const router = useRouter();\n\n  const onPush = () =\u003e {\n    router.push({ path: '/route-path' });\n  };\n\n  const onReplace = () =\u003e {\n    router.replace({ name: 'route-name' });\n  };\n\u003c/script\u003e\n```\n\n#### Outside component tree\n\nIf you need to access the router instance outside of a component, you can instantiate a router instance and pass it to the `RouterContext` or `RouterView` component.\n\n```ts\nimport { Router } from '@dvcol/svelte-simple-router/router';\n\nexport const router = new Router();\n```\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { RouterView } from '@dvcol/svelte-simple-router/components';\n\n  import { router } from './router';\n\u003c/script\u003e\n\n\u003cRouterView {router} /\u003e\n```\n\nRouter navigation support several [options](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L28-L60):\n\n- `name` or `path` to navigate to a named or path route.\n- `params` to pass route parameters.\n- `query` to pass query parameters.\n- `state` to pass an history state object.\n- `meta` to pass an arbitrary object to the route (will be merged with the route meta).\n- `title` to set the document title (will override the route title).\n- `stripQuery` to remove current query parameters from the url.\n- `stripHash` to remove the hash from the url (only in path mode).\n- `stripTrailingHash` to remove the trailing hash from the url (only in hash mode).\n\nYou can also override the router's navigation [options](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L199-L248):\n\n- `base` to set the base path for the router.\n- `hash` to enable hash routing.\n- `strict` to enable strictly match routes (i.e. /path will not match /path/child).\n- `force` to force navigation even if the route is the same.\n- `caseSensitive` to enable case sensitive route names.\n- `failOnNotFound` to throw an error when a route is not found.\n- `metaAsState` to pass the route meta as state when navigating.\n- `nameAsTitle` to set the document title to the route name.\n- `followGuardRedirects` to follow guard redirects.\n\n### Dynamic routes\n\nYou can dynamically [add or remove](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L387-L411) routes from the router instance.\n\nNote that although the inner route map are reactive, adding or removing routes will not trigger a re-synchronization of the router state.\n\nTo force a re-synchronization, you can call the [`sync` method](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L453) on the router instance.\n\nYou can also use the `RouteView` component to declare routes dynamically.\nWhen the component is added to the component tree, the routes will be added to the router instance.\nWhen the component is removed from the component tree, the routes will be removed from the router instance.\n\nRouteView can be passed a `route` object and will add it to the closest router instance.\nAdditionally, if the component/components/redirect are missing, it will try to infer them from the component's children and snippets.\nWhen inside a named `RouterView`, the children will be added to the components object under the `name` key (provided or discovered through context).\n\nRouteView supports the same error and loading snippets as the RouterView component.\nIn addition, named children can be passed as snippets to the component and will be injected into the `components` object.\nIf a snippet with the same `name` as the `RouterView` is found, the children will be injected into the `components` object under the `default` key instead.\n\n**Note**:\nInputs are not reactive, so you will need to un-mout and remount the component to trigger a route update.\nIt is recommended to use the router instance directly if you need to frequently update routes.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import type { PartialRoute } from '@dvcol/svelte-simple-router/models';\n\n  import { RouterContext, RouterView, RouteView } from '@dvcol/svelte-simple-router/components';\n  import { toLazyComponent } from '@dvcol/svelte-simple-router/utils';\n  import ChildComponent from '~/components/goodbye/ChildComponent.svelte';\n  import ParentComponent from '~/components/hello/ParentComponent.svelte';\n\n  const LazyComponent = toLazyComponent(() =\u003e import('./LazyComponent.svelte'));\n\n  const parent: PartialRoute = {\n    name: 'parent',\n    path: '/parent',\n  };\n\n  const child: PartialRoute = {\n    name: 'child',\n    path: '/parent/child',\n  };\n\n\u003c/script\u003e\n\n\u003cRouterContext {options}\u003e\n  \u003cRouterView\u003e\n    \u003cRouteView route={parent}\u003e\n      \u003c!-- Will render the children in this 'default' RouterView --\u003e\n      \u003cParentComponent /\u003e\n\n      \u003c!-- Will render this snippet in the 'nested' RouterView --\u003e\n      {#snippet nested()}\n        \u003cChildComponent /\u003e\n      {/snippet}\n    \u003c/RouteView\u003e\n  \u003c/RouterView\u003e\n\n  \u003cRouterView name=\"nested\"\u003e\n    \u003cRouteView route={parent}\u003e\n      \u003c!-- Will render the children in this 'nested' RouterView, and nothing in the default when  on '/parent/child' --\u003e\n      \u003cChildComponent /\u003e\n    \u003c/RouteView\u003e\n\n    \u003c!-- Inline example --\u003e\n    \u003cRouteView route={{ path: '/other' }} children={ParentComponent} nested={LazyComponent} /\u003e\n  \u003c/RouterView\u003e\n\u003c/RouterContext\u003e\n```\n\n### Guards and listeners\n\n#### Navigation listeners\n\nThe `route` and `router` supports several navigation guards and listeners:\n\n- [beforeEnter](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L269) to run before a route is resolved.\n- [beforeLeave](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L273) to run before a route is removed.\n- [beforeEach](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L420) to run before any route is resolved.\n\nGuards trigger after url change and before the route component is rendered.\n\nIf a guard returns `false`, and object of instance `Error` or `throws`, the navigation will be aborted and the error will be thrown.\n\nIf a guard returns an object with a `path` or `name` property, the navigation will be redirected to the provided route, if any is found and `followGuardRedirects` is enabled.\n\nThe `router` ([dynamically](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L422-L447) or through [options](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L307-L317)) and `RouterView` also support several event listeners:\n\n- `onStart` - executed when the navigation is triggered but before the route is resolved (fires on start and redirects).\n- `onEnd` - executed when the navigation is triggered and the route is resolved (fires on successful and failed navigation, but not on cancelled/redirected).\n- `onError` - executed when the navigation is triggered but an error occurs.\n\nNote: The `onError` listeners passed to a `RouterView` will listen to both the router and view events. If you want to listen to only the router events, you can pass the listeners to the `router` options or instance directly.\n\n#### Loading Listeners\n\nThe `RouterView` supports several view change listeners that triggers once the navigation concludes and the view starts changing.\n\n- `onChange` - executed when a view starts to change.\n- `onLoading` - executed when a view starts loading an async component.\n- `onLoaded` - executed when a view finish loading a component.\n- `onError` - executed when an error occurs during view change.\n\nNote: The `onError` listeners passed to a `RouterView` will listen to both the router and view events. If you want to listen to only the view events, you can pass the listeners to the `view` instance directly.\n\n### Lazy routing\n\nThe `Route` object supports lazy loading of the route component(s).\n\nWhen the `component` property is a lazy import, the router will resolve the matched component before rendering it.\n\nWhile the component is being resolved, the `loading` component will be rendered if any, the `loading` snippet if any, or nothing.\n\nSimilarly, if an error occurs during the component resolution, the `error` component will be rendered if any, the `error` snippet if any, or nothing.\n\nThe router will try to infer if a component is a lazy import by checking it's name (to detect component arrow functions) and it's constructor name (to detect async arrow functions), but for more complex cases, you can use the `toLazyComponent` wrapper.\nNested lazy components require the wrapper to be used or the function to be manually named `component`.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import type { Route } from '@dvcol/svelte-simple-router/models';\n\n  import { RouterView } from '@dvcol/svelte-simple-router/components';\n  import { toLazyComponent } from '@dvcol/svelte-simple-router/utils';\n\n  const routes: Readonly\u003cRoute[]\u003e = [\n    {\n      name: 'lazy',\n      path: '/lazy',\n      component: () =\u003e import('./LazyComponent.svelte'),\n      loading: () =\u003e import('./LoadingComponent.svelte'),\n      error: () =\u003e import('./ErrorComponent.svelte'),\n    },\n    {\n      name: 'lazy-snippet',\n      path: '/lazy-snippet',\n      component: () =\u003e import('./LazyComponent.svelte'),\n    },\n    {\n      name: 'lazy-nested',\n      path: '/lazy-nested',\n      components: {\n        default: async () =\u003e import('./LazyComponent.svelte'),\n        nested: toLazyComponent(() =\u003e import('./NestedComponent.svelte')),\n      },\n    },\n  ] as const;\n\u003c/script\u003e\n\n\u003cRouterView {routes}\u003e\n  {#snippet loading()}\n    \u003ch1\u003eDefault Loading...\u003c/h1\u003e\n  {/snippet}\n\n  {#snippet error(err)}\n    \u003ch1\u003eDefault Error: {err}\u003c/h1\u003e\n  {/snippet}\n\u003c/RouterView\u003e\n```\n\nNote that loading indicator only trigger once the route has been resolved and not on initial navigation.\nIf you want to show a loading indicator on initial navigation, you can use the `routing` snippet instead.\n\nThis means navigation will be a three-step process:\n\n- The `routing` snippet will be rendered.\n- Then the `loading` component will be rendered.\n- Then the route component or error component will be rendered.\n\n### Routes\n\n- Route path supports parameters. Parameters are defined by a colon followed by the parameter name.\n\n```\n/path/:param\n```\n\n- Parameters can be optional by adding a question mark.\n\n```\n/path/:param:?\n```\n\nParameters can also have a type constraint by adding `:{string}` or `:{number}` before the parameter name.\n\nThe router will only match the route if the parameter matches the type constraint.\n\n```\n/path/:{string}:param:?\n```\n\nWill match `/path/param` but not `/path/1`.\n\n```\n/path/:{number}:param\n```\n\nWill match `/path/1` but not `/path/param`.\n\n- Route support wildcards. The `*` character will match any path segment.\n\n```\n/path/*\n```\n\nWill match `/path/param` and `/path/param/param`.\n\n```\n/path/*/:{number}:param/*\n```\n\nWill match `/path/any/12` and `/path/other/12/path/end`.\n\n- Route can have a [redirect](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L164-L170) property to redirect to another route (by path or name).\n- Route can have [components, loadings or errors](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L94-L162) properties to render the route component, loading component or error component respectively (see [lazy-routing](#lazy-routing)).\n- Route can have a [meta](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L236-L239) property to store additional information attached to the route.\n- Route can have a [title](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L232-L235) property to set the document title when the route is active (if `nameAsTitle` is enabled).\n- Route can have [default query or params](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L240-L249) to be used when navigating to the route.\n- Route can have [guard properties](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L266-L273) to run before the route is resolved (see [guards and listeners](#guards-and-listeners)).\n- Route can provide their own [matcher](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L265) object to resolve the active route.\n- Route can have [children](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/route.model.ts#L257) routes that will be parsed by the router instance.\n\n### Router\n\nIn addition to default navigation options (see [programmatic navigation](#programmatic-navigation)), the router instance supports several [options](https://github.com/dvcol/svelte-simple-router/blob/1ca370af1d892f8291d2464145c6a582eeee7438/src/lib/models/router.model.ts#L256-L318):\n\n- `history` to set the history instance the router will use (defaults to global.history).\n- `location` to set the location instance the router will use (defaults to global.location).\n- `listen` to listen to `popstate` or `navigation` events and trigger synchronization.\n- `priority` to set the priority when multiple routes match the current path.\n- `caseSensitive` to enable case sensitive route names.\n- And various [guards and listeners](#guards-and-listeners).\n\n## Author\n\n- Github: [@dvcol](https://github.com/dvcol)\n\n## Show your support\n\nGive a ⭐️ if this project helped you!\n\n \u003ca href=\"https://paypal.me/dvcol/5\" target=\"_blank\"\u003e\n    \u003cimg alt=\"donate\" src=\"https://img.shields.io/badge/Donate%20€-PayPal-brightgreen.svg\" /\u003e\n\u003c/a\u003e\n\n## 📝 License\n\nThis project is [MIT](https://github.com/dvcol/svelte-simple-router/blob/master/LICENSE) licensed.\n\n---\n\n_This README was generated with ❤️ by [readme-md-generator](https://github.com/kefranabg/readme-md-generator)_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvcol%2Fsvelte-simple-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdvcol%2Fsvelte-simple-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvcol%2Fsvelte-simple-router/lists"}