yrv
Version:
Your routing bro!
143 lines (99 loc) • 6.16 kB
Markdown
<div align="center">


[](https://www.npmjs.com/package/yrv)
[](https://snyk.io/test/npm/yrv)
</div>
> The `v` is for Svelte
Built on top of [abstract-nested-router](https://www.npmjs.com/package/abstract-nested-router), so you can use nested routers, also:
- Advanced parameters can be used, e.g. `/:id<\d+>` — [see docs](https://www.npmjs.com/package/abstract-nested-router#params)
- ARIA-compliant, sets `[aria-current="page"]` on active links
- Seamless `<base href="..." />` integration
- Conditionals and redirection through props
- Fallback `<Route />` handlers
- Hash and URI-based routes
- Support for [query-string](https://www.npmjs.com/package/query-string)
- [REPL ready!](https://svelte.dev/repl/0f07c6134b16432591a9a3a0095a80de?version=3.12.1)
> `yrv` will use any _base-href_ found on the current page to rewrite links and routes.
## Usage
Install `yrv` through NPM or Yarn:
```html
<script>
import { Router, Route, Link } from 'yrv';
</script>
<Link href="/">Home</Link>
| <Link href="/World">Hello</Link>
| <Link href="/not/found">NotFound</Link>
<p>
<Router>
<Route exact>Hello World</Route>
<Route fallback>Not found</Route>
<Route exact path="/:name" let:router>Hey {router.params.name}!</Route>
</Router>
</p>
```
> Notice `fallback` routes can’t be placed at the beginning, otherwise further routes will not be mounted. :bomb:
## Components
> You MUST declare at least, one top-level `Router` to setup the bindings.
### `<Router {path} {disabled} {condition} {nofallback} />`
This component will hold any given routes as children, path is always derived from parent ones.
Available props:
- `{path}` — Any segment to derive a fullpath from, default to `/`
- `{disabled}` — Boolean; Similar to condition, but for bound props
- `{condition}` — Function; if given, render only if evaluates to true
- `{nofallback}` — If set, non-matched routes will never raise a failure
### `<Route {key} {path} {props} {exact} {dynamic} {pending} {fallback} {component} {disabled} {condition} {redirect} let:router />`
Main container for routing, they can hold any component or children.
Available props:
- `{key}` — The route identity, not its path; default to random pseudo-hash
- `{path}` — Any segment to derive a fullpath from, default to `/`
- `{props}` — Additional properties for rendered component
- `{exact}` — If set, the route will render only if the route exactly matches
- `{dynamic}` — Promise, if set will resolve and use its result as lazy-component
- `{pending}` — String, this value is rendered during the loading of dynamic components
- `{fallback}` — If set, the route will render only if no more routes were matched
- `{component}` — A valid svelte-component to render if the route matches
- `{disabled}` — Boolean; Similar to condition, but for bound props
- `{condition}` — Function; if given, the route will render only if evaluates to true
- `{redirect}` — Alternate redirection location, only if the previous condition was true
- `let:router` — Injects the `router` context, it also provides `failure` in case of errors
> If you omit `exact`, then `/x` would match both `/` and `/x` routes — [see docs](https://www.npmjs.com/package/abstract-nested-router#params)
### `<Link {go} {href} {title} {exact} {reload} {replace} {class|className} />`
In order to navigate, you can use `Link` components, or regular links, etc.
> All `href` values MUST be absolute, only links starting with `/` or `#` are allowed.
Available props:
- `{go}` — History shortcut (see below)
- `{href}` — New location, default to `/`
- `{title}` — HTML title-attribute value
- `{button}` — If set, will use button-tag instead
- `{exact}` — Determine if link should match exactly to be set as active
- `{reload}` — Use `location.href` instead
- `{replace}` — Use `history.replaceState()` instead
- `{class|className}` — Custom class-name for the mounted anchor
Normal `on:click` events are still allowed, so you can use:
```html
<Link on:click={() => location.reload()}>Reload</Link>
```
> Active _links_ will gain the `[aria-current]` attribute, and `[disabled]` if they're buttons.
Aditionally, you can setup `go` to moving around:
- `"back"` — String; if given, will invoke `history.back()`
- `"fwd"` — String; if given, will invoke `history.fwd()`
- `n` — Number; if given, it'll be used to invoke `history.go(n)`
> If navigating through `history` is not possible a normal redirection will run. :anchor:
## Public API
- `navigateTo(path[, options])` — Change the location, supported options are:
- `reload` — If true, it will use `document.location.href` instead
- `replace` — If true, it will use `history.replaceState()` instead
- `params` — Used to replace `:placeholders` from given path
- `queryParams` — Additional search-params for the new location
- `$router` — Store with shared routeInfo details, similar to `let:router`
> `yrv` gracefully degrades to `location.hash` on environments where `history` is not suitable, also it can be forced through `Router.hashchange = true`.
### IE11 support
Support for IE11 is _granted_ if you include, at least, the following polyfills before your application:
```html
<script>if (!!window.MSInputMethodContext && !!document.documentMode)
document.write('<script src="https://polyfill.io/v3/polyfill.min.js?features=default,Promise,Object.getOwnPropertyDescriptors"><\/script>');</script>
<script src="your-app.js"></script>
```
> `document.write()` is used because conditional comments were dropped in IE10, so this way you can conditionally load polyfills anyway.
Also, you MUST to [enable either `buble` or `babel`](https://github.com/sveltejs/svelte/issues/2621) within your build pipeline to transpile down to ES5.