npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

svero

v1.0.0

Published

Simple Router for Svelte 3

Downloads

40

Readme

npm version Build Status

First things first

svero is intented to be used in SPA (Single Page Applications) making usage of pushState and History API. We're assuming that you already know how to configure your front-end server (being it dev or production) to serve all path requests to index.html.

If you're not familiar with the terms SPA, pushState or History API, you should probably be reading these first:

http://krasimirtsonev.com/blog/article/deep-dive-into-client-side-routing-navigo-pushstate-hash https://css-tricks.com/using-the-html5-history-api/ https://diveinto.html5doctor.com/history.html https://developer.mozilla.org/pt-BR/docs/Web/API/History

Installation

Since it's exported in CommonJS format, you should be using it with a module bundler such as Rollup or Webpack.

You can install svero via npm:

npm install --save svero

Usage

The usage is super simple:

<!-- ./App.svelte -->
<script>
  import { Router, Route } from 'svero';

  import Index from './pages/Index.svelte';
  import About from './pages/About.svelte';
  import Employees from './pages/Employees.svelte';

  let employees = [{ id: 1, name: 'Bill'}, { id:2, name: 'Sven' }];
</script>

<Router>
  <Route path="*" component={Index} />
  <Route path="/about" component={About} />
  <Route path="/about/:who/123/:where" component={About} />
  <Route path="/employees">
    <Employees {employees}/>
  </Route>
</Router>

The * wildcard simply works as a fallback. If a route fails to meet any other path, it then loads the path with the *. If there is no wildcard route and the route did not meet any other path, nothing is loaded.

Your custom props can be passed by putting your component in the Route slot (Employees example above).

Paths with parameters (:param) are passed to components via props: router.params.

Parameters like *param will capture the rest of segments. You can access them as router.params._ like other params.

A component loaded by <Route> receives a property with route details:

<!-- ./pages/About.svelte -->
<script>
  export let router = {};

  // Those contains useful information about current route status
  router.path; // /test
  router.route; // Route Object
  router.params; // /about/bill/123/kansas { who: 'bill', where: 'kansas' }
</script>

Additional properties are passed to the mounted component, e.g.

<Route component={Test} title="Some description" />

Also, you can pass an object:

<Route component={Test} props={myProps} />

Route props are omitted, but all remaining ones are passed to Test.

Routes can also render any given markup when they're active, e.g.

<Route path="/static-path">
  <h1>It works!</h1>
</Route>

You can access router within <slot /> renders by declaring let:router on <Router /> or <Route /> components (see below).

If you're building an SPA or simply want to leverage on hash-based routing for certain components try the following:

<Route path="#g/:gistId/*filePath" let:router>
  <p>Info: {JSON.stringify(router.params)}</p>
</Route>

Standard anchors and <Link /> components will work as usual:

<a href="#g/1acf21/path/to/README.md">View README.md</a>

Declaring a component <Route path="#" /> will serve as fallback when location.hash is empty.

Nesting

You can render svero components inside anything, e.g.

<Router nofallback path="/sub">
  <Route>
    <fieldset>
      <legend>Routing:</legend>
      <Router nofallback path="/sub/:bar">
        <Route let:router>{router.params.bar}!</Route>
      </Router>
      <Route path="/foo">Foo</Route>
      <Route fallback path="*" let:router>
        <summary>
          <p>Not found: {router.params._}</p>
          <details>{router.failure}</details>
        </summary>
      </Route>
      <Router nofallback path="/sub/nested">
        <Route>
          [...]
          <Route fallback path="*">not found?</Route>
          <Route path="/a">A</Route>
          <Route path="/b/:c">C</Route>
          <Route path="/:value" let:router>{JSON.stringify(router.params)}</Route>
        </Route>
      </Router>
    </fieldset>
  </Route>
</Router>

Properties determine how routing will match and render routes:

  • Use the nofallback prop for telling <Router /> to disable the fallback mechanism by default
  • Any route using the fallback prop will catch unmatched routes or potential look-up errors
  • Use the exact prop to skip this route from render just in case it does not matches
  • A <Route /> without path will render only if <Router path="..." /> is active!

Note that all <Router /> paths MUST begin from the root as /sub and /sub/nested in the example.

Redirects

Sometimes you just want a route to send user to another place. You can use the redirect attribute for that.

A redirect should always be a string with a path. It uses the same pattern as path attribute. For a redirect to run, there must be a Route with the equivalent path.

<Router>
  <Route path="/company" redirect="/about-us">
  <Route path="/about-us" component={AboutUs}>
</Router>

Conditions

If you need to meet a condition in order to run a route, you can use the condition attribute. Conditions can also be used with redirect for graceful route fallback.

A condition should be either boolean or a function returning boolean. There is no support for asynchronous conditions at the moment (so keep it simple).

<Router>
  <Route path="/admin/settings" condition={isAdminLogged} redirect="/admin/login">
</Router>

Think of it as a simpler middleware. A condition will run before the route loads your component, so there is no wasteful component mounting, and no screen blinking the unwanted view.

Link Component

There is also an useful <Link> component that overrides <a> elements:

<Link href="path/here" className="btn">Hello!</Link>

The difference between <Link> and <a> is that it uses pushState whenever possible, with fallback to <a> behavior. This means that when you use <Link>, svero can update the view based on your URL trigger, without reloading the entire page.

Given href values will be normalized (on-click) if they don't start with a slash, e.g. when location.pathname === '/foo' then #bar would become /foo#bar as result.

navigateTo()

In some cases you want to navigate to routes programatically instead of letting user click on links. For this scenario we have navigateto() which takes a route as parameter and navigates imediatelly to said route.

navigateTo() receives the same treatment as <Link>: It will always try to use pushState for better performance, fallbacking to a full page redirect if it isn't supported.

Usage:

<script>
  import { onMount } from 'svelte';
  import { navigateTo } from 'svero';

  onMount(() => {
    if (localStorage.getItem('logged')) {
      navigateTo('/admin');
    }
  });
</script>