LitRouter is a simple client side router, component loader (see PRPL) based on page.js. It's designed to work well with Web Components and LitElement.
Inspired by vue-router.
The lit-router package comes with sub package lit-page which is a lightweight web-component that handle display of the selected route and view rendering based on the active attribute.
To import all three classes, just import lit-router global package :
import { LitRouter } from "lit-router";You can also only import what you need :
import { LitRouter } from "lit-router/pkg/dist-src/lit-router/lit-router.js";import "lit-router/pkg/dist-src/lit-page/lit-page.js";Define your routes as an Array of route Objects containing a name, a path, and a component to load (if needed).
Then call router.start(); to activate the router.
You can also define sub routes and add route middlewares.
import { LitRouter } from "lit-router/pkg/dist-src/lit-router/lit-router.js";
// Define your routes and the view component associated
const router = new LitRouter([
  {
    name: "view1",
    path: "/",
    component: () => import("./views/my-view1.js"), // Dynamically import component
    middlewares: [
      (ctx, next) => {
        // Do stuff ...
        next();
      },
    ],
    children: [
      {
        name: "subview1",
        path: "/view1/detail",
        component: () => import("./views/my-detail.js"),
      }
    ]
  }, {
    name: "view2",
    path: "/view2",
    component: () => import("./views/my-view2.js")
  }, {
    name: "view3",
    path: "/view3",
    component: () => import("./views/my-view3.js")
  }, {
    name: "404",
    path: '*',
    middlewares: [
      (ctx, next) => {
        console.log(`Oups, I'm lost π± !!!`);
        next();
      }
    ]
  }
]);
// Start the router
router.start();You can define route guard with the beforeEach method like this :
router.beforeEach((route, ctx, next) => {
  if (route.name == 'view2') { return document.page.redirect('/login'); }
  next();
});Once your have define your routes, you can now listen on the page-changed event fired by the router to detect page changes.
Your can access the current matched route object via document.$router.
The router object expose a getCurrentPage method to retrieve the current view name.
// my-app.js
import { LitElement, html, css } from "lit-element";
// ...
class MyApp extends LitElement {
  constructor() {
    super();
    // Add an event listener on the `page-changed` event
    document.addEventListener('page-changed', () => {
      const router = document.$router;
      this.page = router.getCurrentPage();
    });
  }
  static get properties() {
    return {
      page: String
    };
  }
  static get styles() {
    return css`
      main > * {
        display: none;
      }
      main [active] {
        display: block;
      }
    `;
  } 
  render() {
  	return html`
      <main id="view">
        <my-view1 name="view1" ?active="${this.page == 'view1'}"></my-view1>
        <my-view2 name="view2" ?active="${this.page == 'view2'}"></my-view2>
        <my-view3 name="view3" ?active="${this.page == 'view3'}"></my-view3>
      </main>
	`;
  }
}Import LitRouter from the lit-route ES module.
import { LitRouter } from "./lit-router.js";Then start defining you routes by giving an array of route objects.
Route (option) :
name : The name of the route path. (this option is mandatory).
path : The path that need to be matched. (this option is mandatory).
component : This is used to load the component that need to be displayed for this route. It use dynamic import to load component. See PRPL for more information.
middlewares : An array of middleware function to be executed before the route handler. This function takes two argument, a context object which represent the matched route, and a next method used to pass to the next middleware or route handler.
children : An array of sub route objects.
NOTE  : The child path must be the full path. e.g : /view and /view/details.
lit-page is a simple Web Component, that works with lit-router, that handle the display of the selected view.
Either import the whole lit-router package or just import the lit-page component.
import "lit-router/pkg/dist-src/lit-page/lit-page.js";// my-app.js
import { LitElement, html, css } from "lit-element";
import "lit-router/pkg/dist-src/lit-page/lit-page.js";
// ...
class MyApp extends LitElement {
  render() {
  	return html`
      <lit-page>
        <my-view1 name="view1" data-animation="page-enter"></my-view1>
        <my-view2 name="view2"></my-view2>
        <my-view3 name="view3"></my-view3>
        <section name="404">
          <h1>Oups, I'm lost π± !!!</h1>
        </section>
      </lit-page>
	`;
  }
}attrForSelected		String	= 	'name'
The attrForSelected property can be used to define the selective attribute to use on view component or tags
page-changed
The page-changed event is fired when navigating to different page
LitPage provide a simple way to handle transition between pages with the data attribute data-animation.
There is two values for this attribute :
- page-enter (default)
- page-leave