{"id":13806745,"url":"https://github.com/shaunlee/svelte-router","last_synced_at":"2025-10-25T00:30:47.631Z","repository":{"id":59449055,"uuid":"537337679","full_name":"shaunlee/svelte-router","owner":"shaunlee","description":"Another vue-router inspired Svelte router","archived":false,"fork":false,"pushed_at":"2024-02-20T04:28:59.000Z","size":58,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-29T18:05:51.963Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/shaunlee.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-16T06:43:06.000Z","updated_at":"2024-01-14T08:27:35.000Z","dependencies_parsed_at":"2024-08-04T01:06:38.526Z","dependency_job_id":null,"html_url":"https://github.com/shaunlee/svelte-router","commit_stats":{"total_commits":35,"total_committers":1,"mean_commits":35.0,"dds":0.0,"last_synced_commit":"03875cda416703dc1dc898e5d6a483ca3037ad2e"},"previous_names":["shaunlee/svelterouter"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaunlee%2Fsvelte-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaunlee%2Fsvelte-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaunlee%2Fsvelte-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaunlee%2Fsvelte-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shaunlee","download_url":"https://codeload.github.com/shaunlee/svelte-router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236632811,"owners_count":19180476,"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":[],"created_at":"2024-08-04T01:01:15.535Z","updated_at":"2025-10-25T00:30:42.380Z","avatar_url":"https://github.com/shaunlee.png","language":"JavaScript","funding_links":[],"categories":["Routers"],"sub_categories":["Internationalisation"],"readme":"# Svelte Router\n\nAnother vue-router inspired Svelte router\n\n## Installation\n\n### npm\n\n```bash\nnpm install @shaun/svelte-router\n```\n\n### yarn\n\n```bash\nyarn add @shaun/svelte-router\n```\n\n## Getting Started\n\n```html\n\u003cscript\u003e\n  import { createRouter, link, Link, View } from '@shaun/svelte-router'\n  import Home from './Home.svelte'\n  import User from './User.svelte'\n  import NotFound from './NotFound.svelte'\n\n  const routes = [\n    { path: '/', component: Home },\n    { path: '/users/:userId(\\\\d+)', component: User },\n    { path: '*', component: NotFound }\n  ]\n\n  const router = createRouter({ routes })\n\u003c/script\u003e\n\n\u003cLink href=\"/\"\u003eHome\u003c/Link\u003e\n\u003cLink href=\"/users/123\"\u003eSomeone\u003c/Link\u003e\n\u003cLink href=\"/users/321\" replace\u003eReplace to someone else's page\u003c/Link\u003e\n\u003ca use:link href=\"/users/111\"\u003ea link with action\u003c/a\u003e\n\u003cLink href=\"/not-exists\"\u003eTo page not exists\u003c/Link\u003e\n\u003cbutton type=\"button\" on:click={() =\u003e router.push('/users/123')}\u003eClick to someone's page\u003c/button\u003e\n\u003cbutton type=\"button\" on:click={() =\u003e router.replace('/users/321')}\u003eClick replace to someone else's page\u003c/button\u003e\n\n\u003cView\u003e\u003c/View\u003e\n```\n\nUser.svelte\n\n```html\n\u003cscript\u003e\n  export let userId // take router params\n\u003c/script\u003e\n\n\u003cdiv\u003eUser ID: {userId}\u003c/div\u003e\n```\n\n## Example\n\n[https://github.com/shaunlee/svelte-router/tree/master/example](https://github.com/shaunlee/svelte-router/tree/master/example)\n\n## Dynamic Route Matching with Params\n\nVery often we will need to map routes with the given pattern to the same component. For example we may have a `User` component which should be rendered for all users but with different user IDs. In `@shaun/svelte-router` we can use a dynamic segment in the path to achieve that, we call that a param:\n\n```javascript\nimport User from './User.svelte'\n\n// these are passed to `createRouter`\nconst routes = [\n  // dynamic segments start with a colon\n  { path: '/users/:id', component: User },\n]\n```\n\nNow URLs like `/users/johnny` and `/users/jolyne` will both map to the same route.\n\nA param is denoted by a colon `:`. When a route is matched, the value of its params will be exposed as `$router.params`. Therefore, we can render the current user ID by updating User's template to this:\n\n```html\n\u003cscript\u003e\n  import { router } from '@shaun/svelte-router'\n\u003c/script\u003e\n\n\u003cdiv\u003eUser ID: {$router.params.id}\u003c/div\u003e\n```\n\nThe same:\n\n```html\n\u003cscript\u003e\n  export let id\n\u003c/script\u003e\n\n\u003cdiv\u003eUser ID: {id}\u003c/div\u003e\n```\n\nYou can have multiple params in the same route, and they will map to corresponding fields on `$router.params`. Examples:\n\n| pattern | matched path | $router.params |\n| --- | --- | --- |\n| /users/:username | /users/eduardo | `{ username: 'eduardo' }` |\n| /users/:username/posts/:postId | /users/eduardo/posts/123 | `{ username: 'eduardo', postId: '123' }` |\n\nIn addition to `$router.params`, the `$router` object also exposes other useful information such as `$router.query` (if there is a query in the URL), `$router.path`, etc.\n\n## Routes' Matching Syntax\n\nMost applications will use static routes like `/about` and dynamic routes like `/users/:userId` like we just saw in Dynamic Route Matching, but `@shaun/svelte-router` has much more to offer!\n\n### Custom regex in params\n\nWhen defining a param like `:userId`, we internally use the following regex `([^/]+)` (at least one character that isn't a slash `/`) to extract params from URLs.\nThis works well unless you need to differentiate two routes based on the param content. Imagine two routes `/:orderId` and `/:productName`, both would match the exact same URLs, so we need a way to differentiate them.\nThe easiest way would be to add a static section to the path that differentiates them:\n\n```javascript\nconst routes = [\n  // matches /o/3549\n  { path: '/o/:orderId' },\n  // matches /p/books\n  { path: '/p/:productName' },\n]\n```\n\nBut in some scenarios we don't want to add that static section `/o/p`. However, `orderId` is always a number while `productName` can be anything, so we can specify a custom regex for a param in parentheses:\n\n```javascript\nconst routes = [\n  // /:orderId -\u003e matches only numbers\n  { path: '/:orderId(\\\\d+)' },\n  // /:productName -\u003e matches anything else\n  { path: '/:productName' },\n]\n```\n\nNow, going to `/25` will match `/:orderId` while going to anything else will match `/:productName`. The order of the `routes` array doesn't even matter!\n\n\u003e **TIP**\n\u003e Make sure to escape backslashes (`\\`) like we did with `\\d` (becomes `\\\\d`) to actually pass the backslash character in a string in JavaScript.\n\n## Programmatic Navigation\n\nAside from using `\u003cLink\u003e` to create anchor tags for declarative navigation, we can do this programmatically using the router's instance methods.\n\n### Navigate to a different location\n\nTo navigate to a different URL, use `router.push`. This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.\n\nThis is the method called internally when you click a `\u003cLink\u003e`, so clicking `\u003cLink href=\"...\"\u003e` is the equivalent of calling `router.push(...)`.\n\n| Declarative | Programmatic |\n| --- | --- |\n| `\u003cLink href=\"...\"\u003e` | `router.push(...)` |\n\nThe argument is a string path. Examples:\n\n```javascript\nrouter.push('/users/eduardo')\n\nrouter.push('/users?page=2')\nrouter.push('/users', { page: 2 })\n```\n\n### Replace current location\n\nIt acts like `router.push`, the only difference is that it navigates without pushing a new history entry, as its name suggests - it replaces the current entry.\n\n| Declarative | Programmatic |\n| --- | --- |\n| `\u003cLink href=\"...\" replace\u003e` | `router.replace('...')` |\n\n### Traverse history\n\nThis method takes a single integer as parameter that indicates by how many steps to go forward or go backward in the history stack, similar to `window.history.go(n)`. Examples:\n\n```javascript\n// go forward by one record, the same as router.forward()\nrouter.go(1)\n\n// go back by one record, the same as router.back()\nrouter.go(-1)\n\n// go forward by 3 records\nrouter.go(3)\n\n// fails silently if there aren't that many records\nrouter.go(-100)\nrouter.go(100)\n```\n\n### History Manipulation\n\nYou may have noticed that `router.push`, `router.replace` and `router.go` are counterparts of `window.history.pushState`, `window.history.replaceState` and `window.history.go`, and they do imitate the `window.history` APIs.\n\nTherefore, if you are already familiar with [Browser History APIs](https://developer.mozilla.org/en-US/docs/Web/API/History_API), manipulating history will feel familiar when using `@shaun/svelte-router`.\n\nIt is worth mentioning that `@shaun/svelte-router` navigation methods (push, replace, go) work consistently no matter the kind of `mode` option is passed when creating the router instance.\n\n## Different History modes\n\nThe `mode` option when creating the router instance allows us to choose among different history modes.\n\n### Hash Mode\n\nThe hash history mode is created with `'hash'`:\n\n```javascript\nimport { createRouter } from '@shaun/svelte-router'\n\nconst router = createRouter({\n  mode: 'hash',\n  routes: [\n    // ...\n  ]\n})\n```\n\nIt uses a hash character (`#`) before the actual URL that is internally passed. Because this section of the URL is never sent to the server, it doesn't require any special treatment on the server level. It does however have a bad impact in SEO. If that's a concern for you, use the HTML5 history mode.\n\n### HTML5 Mode\n\nThe HTML5 mode is created with `'web'` and is the recommended mode:\n\n```javascript\nimport { createRouter } from '@shaun/svelte-router'\n\nconst router = createRouter({\n  mode: 'web',\n  routes: [\n    // ...\n  ]\n})\n```\n\nWhen using `'web'`, the URL will look \"normal,\" e.g. `https://example.com/user/id`. Beautiful!\n\nHere comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access `https://example.com/user/id` directly in their browser. Now that's ugly.\n\nNot to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same `index.html` page that your app lives in. Beautiful, again!\n\n## Example Server Configurations\n\nNote: The following examples assume you are serving your app from the root folder. If you deploy to a subfolder, you should use the `vite build --base=/prefix/` and the related base property of the router.\nYou also need to adjust the examples below to use the subfolder instead of the root folder (e.g. replacing RewriteBase `/` with RewriteBase `/name-of-your-subfolder/`).\n\n### Apache\n\n```apacheconf\n\u003cIfModule mod_negotiation.c\u003e\n  Options -MultiViews\n\u003c/IfModule\u003e\n\n\u003cIfModule mod_rewrite.c\u003e\n  RewriteEngine On\n  RewriteBase /\n  RewriteRule ^index\\.html$ - [L]\n  RewriteCond %{REQUEST_FILENAME} !-f\n  RewriteCond %{REQUEST_FILENAME} !-d\n  RewriteRule . /index.html [L]\n\u003c/IfModule\u003e\n```\n\nInstead of `mod_rewrite`, you could also use [`FallbackResource`](https://httpd.apache.org/docs/2.2/mod/mod_dir.html#fallbackresource).\n\n### nginx\n\n```nginx\nlocation / {\n  try_files $uri $uri/ /index.html;\n}\n```\n\n### Caddy v2\n\n```\ntry_files {path} /\n```\n\n### Firebase hosting\n\nAdd this to your `firebase.json`:\n\n```json\n{\n  \"hosting\": {\n    \"public\": \"dist\",\n    \"rewrites\": [\n      {\n        \"source\": \"**\",\n        \"destination\": \"/index.html\"\n      }\n    ]\n  }\n}\n```\n\n## License\n\nLicensed under [MIT](https://github.com/shaunlee/svelte-router/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaunlee%2Fsvelte-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshaunlee%2Fsvelte-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaunlee%2Fsvelte-router/lists"}