{"id":13735537,"url":"https://github.com/zyxd/svelte-store-router","last_synced_at":"2025-05-08T11:33:32.526Z","repository":{"id":45446610,"uuid":"306996164","full_name":"zyxd/svelte-store-router","owner":"zyxd","description":"Store-based router for Svelte","archived":true,"fork":false,"pushed_at":"2021-12-13T15:10:46.000Z","size":109,"stargazers_count":91,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-20T08:40:46.844Z","etag":null,"topics":["browser","frontend","javascript","node","router","ssr","state","store","svelte","svelte-pathfinder"],"latest_commit_sha":null,"homepage":"https://svelte-store-router-demo.vercel.app","language":"JavaScript","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/zyxd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-10-25T00:29:31.000Z","updated_at":"2023-12-21T14:31:41.000Z","dependencies_parsed_at":"2022-07-30T18:08:05.492Z","dependency_job_id":null,"html_url":"https://github.com/zyxd/svelte-store-router","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyxd%2Fsvelte-store-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyxd%2Fsvelte-store-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyxd%2Fsvelte-store-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyxd%2Fsvelte-store-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zyxd","download_url":"https://codeload.github.com/zyxd/svelte-store-router/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253059405,"owners_count":21847287,"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":["browser","frontend","javascript","node","router","ssr","state","store","svelte","svelte-pathfinder"],"created_at":"2024-08-03T03:01:07.915Z","updated_at":"2025-05-08T11:33:32.185Z","avatar_url":"https://github.com/zyxd.png","language":"JavaScript","funding_links":[],"categories":["Browser Navigation"],"sub_categories":[],"readme":"# Store-based router for Svelte | [Demo](https://svelte-store-router-demo.vercel.app)\n\n#### Inspired by the [svelte-pathfinder](https://github.com/PaulMaly/svelte-pathfinder) by [PaulMaly](https://github.com/PaulMaly)\n\nA 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.\n\n#### [How it works](https://www.youtube.com/watch?v=kf5zccSyEso) (russian language)\n\n## Features\n\n- Just another global state;\n- It doesn't impose any restrictions on how to apply this state to the application;\n- Manipulate different parts of a state (`path` / `query` / `fragment`) separately;\n- Automatic parsing of the `query` and `fragment` parameters;\n- Components for `path` matching and parameters extracting (using [regexparam](https://github.com/lukeed/regexparam));\n- Configurable delay of `History` changing;\n- Converting `query` and `fragment` string values to JavaScript types;\n- Cleaning `query` and `fragment` from empty values like a `null` / `undefined` / `''`;\n- Automatically handling `\u003ca\u003e` navigation what allow updating the route state without reloading the page;\n- Works fine with SSR.\n\n## Install\n\n```bash\nnpm i svelte-store-router --save-dev\n```\n\n## Usage\n\nCreate a route store in your `stores.js`:\n```javascript\nimport { createRouteStore } from 'svelte-store-router'\n\nexport const route = createRouteStore({\n  delay: 300,\n  queryClean: true,\n  fragmentClean: true\n})\n```\n\nNow you can access it as usual store.\n```svelte\n\u003cscript\u003e\n  import { route } from './stores.js'\n\u003c/script\u003e\n\nFull route:   {$route}\nPath:         {$route.path}\nQuery:        {$route.query}\nFragment:     {$route.fragment}\n```\n\nYou can change it.\n```svelte\n\u003cbutton on:click={() =\u003e $route.path = '/'}\u003ehome page\u003c/button\u003e\n\u003cbutton on:click={() =\u003e $route.path = '/users'}\u003euser list\u003c/button\u003e\n\n\u003cbutton on:click={() =\u003e $route.query.sort = 'name'}\u003esort by name\u003c/button\u003e\n\u003cbutton on:click={() =\u003e $route.query.team = 'svelte'}\u003efilter by team\u003c/button\u003e\n\n\u003cbutton on:click={() =\u003e $route.fragment.modal = true}\u003eopen modal window\u003c/button\u003e\n\u003cbutton on:click={() =\u003e $route.fragment.scroll = 5}\u003eskip first 50 users\u003c/button\u003e\n```\n\nYou can bind store values.\n```svelte\n\u003ctextarea placeholder=\"fragment.search\" bind:value={$route.fragment.search}/\u003e\n```\n\nYou 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`.\n```svelte\n\u003cbutton on:click={() =\u003e $route = '/users?orderBy=karma\u0026limit=10'}\u003eshow top 10 users\u003c/button\u003e\n\u003cbutton on:click={() =\u003e route.goto('/users?orderBy=karma\u0026limit=10')}\u003eshow top 10 users\u003c/button\u003e\n```\n\nYou can match path pattern and parametrize it ([regexparam](https://github.com/lukeed/regexparam)).\n```svelte\n\u003cscript\u003e\n  import { Match } from 'svelte-store-router'\n  import { route } from './stores.js'\n\u003c/script\u003e\n\n\u003cMatch route={$route} pattern=\"/users\"\u003e\n  User list\n\u003c/Match\u003e\n\u003cMatch route={$route} pattern=\"/users/:id\" let:params={{ id }}\u003e\n  User {id} profile\n\u003c/Match\u003e\n```\n\nYou can show only first matching path.\n```svelte\n\u003cscript\u003e\n  import { Match, Matcher } from 'svelte-store-router'\n  import { route } from './stores.js'\n\u003c/script\u003e\n\n\u003cMatcher\u003e\n  \u003cMatch route={$route} pattern=\"/users\"\u003e\n    User list\n  \u003c/Match\u003e\n  \u003cMatch route={$route} pattern=\"/users/:id\" let:params={{ id }}\u003e\n    User {id} profile\n  \u003c/Match\u003e\n  \u003cMatch route={$route}\u003e\n    Page not found\n  \u003c/Match\u003e\n  \u003cMatch route={$route}\u003e\n    This content will never be displayed, because\n    the previous \u003cMatch\u003e handle all possible routes\n  \u003c/Match\u003e\n\u003c/Matcher\u003e\n```\n\nYou can use nested match components using the `loose` parameter.\n```svelte\n\u003cscript\u003e\n  import { Match, Matcher } from 'svelte-store-router'\n  import { route } from './stores.js'\n\u003c/script\u003e\n\n\u003cMatcher\u003e\n  \u003cMatch route={$route} pattern=\"/users\" loose\u003e\n    Begin of users template\n    \u003cMatcher\u003e\n      \u003cMatch route={$route} pattern=\"/users\"\u003e\n        Users list\n      \u003c/Match\u003e\n      \u003cMatch route={$route} pattern=\"/users/:id\" let:params={{ id }}\u003e\n        User {id} profile\n      \u003c/Match\u003e\n    \u003c/Matcher\u003e\n    End of users template\n  \u003c/Match\u003e\n  \u003cMatch route={$route}\u003e\n    Page not found\n  \u003c/Match\u003e\n\u003c/Matcher\u003e\n```\n\nOr you can do it all above manually using `match` function instead of components.\n```svelte\n\u003cscript\u003e\n  import { match } from 'svelte-store-router'\n  import { route } from './stores'\n\n  let params\n\u003c/script\u003e\n\n\u003c!--\n  It is recommended to first check if the route matches the base path of application by \n  calling `match($route)`. Not necessary if the application will always be in the root path.\n--\u003e\n{#if match($route)}\n  {#if match($route, '/users', true)}\n    Begin of users template\n    \n    {#if params = match($route, '/users/:id')}\n      User {params.id}\n    {:else if params = match($route, '/users/:id/friends')}\n      User {params.id} friends\n    {/if}\n\n    End of users template\n  {:else}\n    Page not found\n  {/if}\n{/if}\n```\n\n## Options\n\n#### base [String]\nBase path of application. Routes and links which not match under this path will not be handled. `''` by default.\n\n#### delay [Number]\nSets 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.\n\n#### queryParse, fragmentParse [Boolean]\nEnables `query` and `fragment` string to objects conversion. `true` by default.\n\n#### queryTyped, fragmentTyped [Boolean]\nConverts query and fragment string values to JavaScript types. `true` by default. For example strings will be converted from -\u003e to:\n```\n\"1\"         -\u003e 1\n\"0.123\"     -\u003e 0.123\n\"true\"      -\u003e true\n\"null\"      -\u003e null\n\"undefined\" -\u003e undefined\n\"01234\"     -\u003e 1234\n\"a1234\"     -\u003e \"a1234\"\n```\n\n#### queryClean, fragmentClean [Boolean]\nClean query and fragment from empty (`null` / `undefined` / `\"\"`) values. Might be useful to avoid `/path?page=undefined\u0026search=`. `false` by default.\n\n#### queryShortBoolean, fragmentShortBoolean [Boolean]\nAutomatically shortens the parameter string for boolean values, e.g. `a=true\u0026b=false\u0026c=true` into `a\u0026c`. So for parameters with `true` only the parameter name will be shown, and with `false` they will be hidden completely. `false` by default.\n\n#### sideEffect [Boolean]\nControls side effect of route changing which push items to History. `true` by default in browser, always `false` on server side.\n\n#### handleNavigation [Boolean / String]\nToggles a navigation handler that automatically intercepts `\u003ca\u003e` clicks, updating the route state without reloading the page. Adding a `rel=\"external\"` attribute to a `\u003ca\u003e` 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 `\u003ca\u003e` clicks should be handled. `true` by default.\n\n#### autoClearParams [Boolean]\nThis option toggles automatically clear the `query` and `fragment` when the `path` is changed. `false` by default.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzyxd%2Fsvelte-store-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzyxd%2Fsvelte-store-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzyxd%2Fsvelte-store-router/lists"}