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

a-wc-router

v2.3.0

Published

AWC Router, Simple, Declarative, Decoupled, Web Component Router, PRPL, Router, Routing, Outlet

Downloads

216

Readme

AWC Router

Build Status

Features

  • Web Component
  • Code splitting/lazy loading
  • Declarative routing
  • Nested routing
  • Named/auxiliary routing and outlets
  • Path params
  • Guards
  • Works with regular anchor tags for links
  • Automatically styling active links
  • Zero dependencies

Examples

Examples and further documentation can be found in the examples folder and are hosted here

To run the examples locally run:

node exampleServer.js

Then enter this url in the browser:

http://localhost:3000/a-wc-router/examples/router/

Install

npm i a-wc-router

Usage

With HTML

<!DOCTYPE html>
<html>
    <head>
        <base href="/app/">
        <script type="module" src="/node_modules/a-wc-router/build/es6-bundled/src/router.js"></script>
        OR use a CDN
        <script type="module" src="https://unpkg.com/a-wc-router/src/router.js"></script>
        <script type="module" src="https://cdn.jsdelivr.net/npm/a-wc-router/src/router.js"></script>
        
        <script type="module" src="/src/my-page1.js"></script>
    </head>
    <body>
        <a is="router-link" href="/app/page1">Page 1</a>
        <a is="router-link" href="/app/page2">Page 2</a>
        <a-router  style="display: block;">
            <a-outlet>This content never shows because of the last catch all route</a-outlet>
            <a-route path="/page1" element="my-page1"></a-route>
            <a-route path="/page2" element="my-page2" import="/src/my-page2.js"></a-route>
            <a-route path="*"><template>Page not found</template></a-route>
        </a-router>
    </body>
</html>

With Custom Element

import '../node_modules/a-wc-router/build/es6-bundled/src/router.js';
// Or use a CDN
import 'https://unpkg.com/a-wc-router/src/router.js';
import 'https://cdn.jsdelivr.net/npm/a-wc-router/src/router.js';

import './my-page1.js';

class MyApp extends HTMLElement {
    connectedCallback() {
        if (this.isConnected) {
            this.innerHTML =   `
                <a is="router-link" href="/app/page1">Page 1</a>
                <a is="router-link" href="/app/page2">Page 2</a>
                <a-router  style="display: block;">
                    <a-outlet>This content never shows because of the last catch all route</a-outlet>
                    <a-route path="/page1" element="my-page1"></a-route>
                    <a-route path="/page2" element="my-page2" import="/src/my-page2.js"></a-route>
                    <a-route path="*"><template>Page not found</template></a-route>
                </a-router>
            `;
        }
    }
}

customElements.define('my-app', MyApp);

Routing

Routing using a router, outlet, routes and HTML anchors

<a-router>
    <a-outlet>Please click a link</a-outlet>
    <a-route path="/user" import="./userBundle.js" element="user-main"></a-route>
    <a-route path="/item" import="./itemsBundle.js" element="item-main"></a-route>
    <a-route path="/template"><template>Hello Template</template></a-route>
    <a-route path="*"><template></template></a-route>
<a-router>
....
<a href='user'>click for user-main custom element</a>
<a href='item'>click for item-main custom element</a>

Passing data to routes

<a-route path="/user1/:requiredParam" element="user-main"></a-route>
<a-route path="/user2/:optionalParam?" element="user-main"></a-route>
<a-route path="/user2/:optionalParam?defaultValue" element="user-main"></a-route>
<a-route path="/user3/:atLeastOneParam+" element="user-main"></a-route>
<a-route path="/user4/:anyNumOfParam*" element="user-main"></a-route>
<a-route path="/user5/:firstParam/:secondParam" element="user-main"></a-route>
<!-- use a '.' as first char to set data as a property of the element instead of  an attribute -->
<a-route path="/user5/:.dataAsPropertyInsteadOfAttribute" element="user-main"></a-route>

<!-- constant params via attributes -->
<a-route path="/user6" data-firstParam="valueA" data-secondParam="valueB" element="user-main">
    <!-- This create <user-main firstParam="valueA" secondParam="valueB"> but will be overridden by values in the route -->
</a-route>
<script>
    // Constant params via set properties
    const myRoute = document.querySelector('a-route');
    // Set constant param programmatically
    myRoute.firstParam = 'valueA';
    myRoute.secondParam = new Date();
    // This will set the firstParam and secondParam as properties on the route content
</script>
<a href="user1/12">click for user with required param</a>
<a href="user2">click for user with optional param</a>
<a href="user3/12/tom">click for user with at least one param</a>
<a href="user4/12/tom">click for user any number of params</a>
<a href="user5/12/tom">click for user with two named params</a>

Code splitting and eager loading modules for routes

<a-route path="/user" import="/path-to/user-main.js" element="user-main"></a-route>

Code splitting and lazy loading modules for routes

<a-route path="/user" import="/path-to/user-main.js" lazy-load element="user-main"></a-route>

Nested Routing

<a-router>
    <a-outlet></a-outlet>
    <a-route path="/user" import="./userBundle.js" element="user-main"></a-route>
    <a-route path="/item" import="./itemsBundle.js" element="item-main"></a-route>
    <a-route path="*"><template></template></a-route>
<a-router>

// Code snippet from user-main with nested routing
connectedCallback() {
    if (this.connected && !this.innerHTML) {
        this.innerHTML = `
            <a-router>
                <a-outlet></a-outlet>
                <a-route path="/details" element="user-details"></a-route>
                <a-route path="/edit" element="user-edit"></a-route>
            </a-route>
            `;
    }
}
....
<a href='/user/details'>Navigate to the nested route</a>

Base URL

Routing only takes place if a url also matches the document.baseURI.

<base href="/MyAppRoot/">

<a href='/user'>Wont route</a>
<a href='/MyAppRoot/user'>Will route</a>

Named outlets (no router or routes required)

Routing using named outlets and HTML anchors

<a-outlet name="main">Please click a link</a-outlet>
....
<a href="/(main:user-main)">Assign <user-main> element to outlet main</a>
<a href="/(main:item-main)">Assign <item-main> element to outlet</a>

Passing data to named outlets

<a-outlet name="main">Please click a link</a-outlet>
....
<a href="/(main:user-main:userId=2&userName=tom)">Assign <user-main userId="2" userName="tom"> to outlet</a>

Code splitting and eager loading modules for named outlets

<a-outlet name="main">Please click a link</a-outlet>
....
<a class="item" is="router-link" href="(main:user-main(/path-to/user-main.js))">Load <user-main> from /path-to/user-main.js</a>
<a class="item" is="router-link" href="(main:/path-to/user-main)">Load <user-main> from /path-to/user-main.js</a>

General to Routing and Named Outlets

Styling link matching the active routes

<style>
    a.active {
        color: red;
    }
</style>

<a class="item" href="/user/123">Regular anchor - will route but wont get active status styling</a>
<a is="router-link" class="item" href="/user/123">Router link - will route and get active status styling</a>

Navigating using HTML anchors

<a class="item" href="/user/123">Regular anchor - will route but wont get active status styling</a>
<a is="router-link" class="item" href="/user/123">outer link - will route and get active status styling</a>

Navigating using events

window.dispatchEvent(
    new CustomEvent(
        'navigate', {
            detail: {
                href: '/(user/123' }}));

Navigating using RouterElement

RouterElement.navigate('myUrl');
RouterElement.navigate('/user/123');

Guards

window.addEventListener('onRouteLeave', guard);

guard(event) {
    if (document.getElementById('guard').checked) {
        // preventDefault to prevent the navigation
        event.preventDefault();
    }
}

Lifecycle Events

onRouterAdded

onRouteMatch

onRouteLeave

onRouteNotHandled

onRouteCancelled

onLinkActiveStatusUpdated

onOutletUpdated

Testing

To run tests:

npm test