A client-side, webcomponent based router for lightning fast page navigation. With Capacitor, you send the entire site all at once and let it decide what's shown.

Don't believe me when I say it's fast? Try clicking some links. Neat! It even recognizes hashes!

Download
https://capacitor.non.io/capacitor.js6.2kb

How it works

If you inspect this page, you'll notice this landing page is contained in a

<capacitor-route path="^$" script="pages/home.js" fresh active>

Since the url path matches the path, the route knows to activate itself. Routes that aren't currently active remove themselves from the DOM tree.

How is this different than React?

Two main differences. First and foremost with CapacitorJS you send every page at once on the initial page load, which Capacitor then caches for page navigation. This means navigating between pages on your site will take about a single frame to render since it doesn't need to contact the server, making for a super snappy experience. For extremely large sites however, React would still be a better choice simply because the initial payload would be too large.

The other difference is it makes for a somewhat more declarative DOM. The DOM shows the entire structure of the site, which makes things a little more transparent. You can argue whether or not this is a good or a bad thing.

Wont <a> tags force a page refresh though?

Yea toats. That's why we use a happy helper tag for links:

<capacitor-link href="wow">Hello, world</capacitor-link>
I still think you're dumb - you'll have like 8 scripts all trying to run on DOMContentLoaded!

Agree with the first part, but as for the second you can add listeners to the routeactivate event. You can also specify a script attribute for the route as a shorthand to bind to a few events:

<capacitor-route path=".*" script="hello.js"> 
  <h1>Hello, world</h1> 
<capacitor-route>
({
  // Runs once as soon as the page loads
  init: () => {
  },

  // Runs every time the route is activated
  onActivate: () => {
    console.log('I was activated!')
  },

  // Runs every time the route is deactivated
  onDeactivate: () => {
    console.log('Apparently the other pages were cooler')
  }
})

Wow that was so fast!

Feel free to click the back button - Capacitor takes advantage of javascript history states, so you can navigate naturally.

capacitor-route

The container for routes. These dynamically remove and re-add their content whenever they're active.

<capacitor-route path="/foo">...</capacitor-route>
path
// path can be an absolute path
<capacitor-route path="/foo">...</capacitor-route>

// path can also be a regex
<capacitor-route path="^[a-z][0-9]$">...</capacitor-route>
script

Routes can have a script associated with them that have three functions: init (ran when the page loads), onActivate (ran whenever the route activates), and onDeactivate.

// routes can have a script associated with them
<capacitor-route path="foo" script="foo.js">...</capacitor-route>
// foo.js

({
  // Runs once as soon as the page loads
  init: () => {
  },

  // Runs every time the route is activated
  onActivate: () => {
    console.log('I was activated!')
  },

  // Runs every time the route is deactivated
  onDeactivate: () => {
    console.log('Apparently the other pages were cooler')
  }
})
test

Specifies what part of the url to test. Can be path (default), hash, or both.

// this will match /foo, as well as /foo#asdf. 
<capacitor-route path="/foo" test="path">...</capacitor-route>

// this will match /foo, but not /foo#asdf. 
<capacitor-route path="/foo" test="both">...</capacitor-route>

// this will match any path that has #foo at the end.
<capacitor-route path="foo" test="hash">...</capacitor-route>
fresh

Boolean attribute, default is false. If true, the route will load a fresh version of the DOM inside of it. If false, will use the previous state of the DOM. A good example of this is if the page has a <textarea> tag, and the textarea has some text in it, if fresh is false that text will still be present if you navigate away and back. If it's true, the textarea will be empty.

<capacitor-route path="/foo" fresh>...</capacitor-route>

capacitor-link

A replacement for <a> tags. Links will trigger a url update without causing a page fresh, and the router will detect and delegate accordingly to activate the correct routes.

<capacitor-link href="foo">foo<capacitor-link>
fresh

Boolean attribute, default is false. If true, it forces the route that it matches to load a fresh version of the DOM inside of it. If false, will use the previous state of the DOM. A good example of this is if the page has a <textarea> tag, and the textarea has some text in it, if fresh is false that text will still be present if you navigate away and back. If it's true, the textarea will be empty.

<capacitor-link href="foo" fresh>foo<capacitor-link>