Clientside Routing in <1kb

TL:DR; demo, source - on npm as element-router

It probably won’t come as a big surprise but I’m a big fan of the web and standards. I’m pretty excited about where browsers are going, and how thats going to change the landscape of frameworks and libraries. We’ve seen this before with browsers adopting features from jQuery like querySelector and promises. Frameworks started relying on components as their main building-block, which pushed the browsers to include webcomponents. In just a couple of years, all the frameworks will utilise these features instead of building them on their own, resulting in better performance, less javascript to download, parse and execute, and eventually just better user experiences.

Playing around with native webcomponents, trying to build a real world app, I realised that with the fetch-api for ajax and es-modules all I really needed to build complex applications were a router. So I set out to build one. I wanted to keep it super simple, modern and with a very light footprint (thats where the <1kb challenge came from)

If you just wan’t to check out the source, or see a demo, you should just swing by the GitHub-repo https://github.com/filipbech/element-router. In this blogpost, I’ll focus on how to use this new thing.

The configuration is similar to that of the Preact-router — which is where I got a lot of inspiration (and stole/borrowed some of the dynamic routing code). If you look at this, your intuition might tell you how if works. If not, or if you are in doubt — read on below.

The building block is the element-router element. You put this tag where you wan’t the routers “outlet” to be. Inside it you configure the router by putting in element-route elements with appropriate attributes. You must provide a path-attribute which is a string with the url (or url-scheme) that should match this route. The order of the element-route elements determines what element-route to use if a url matches more than one element-route’s path.

If you want part of a path to be a variable, you can use a special syntax where you put a colon ´:´ in the path. That part of the url will be handled as a variable, and the corresponding value (from the actual url) will be assigned as a property on the element being rendered. (in the example that means the product-page element would be rendered, having a property uid with the value 123 if the url was /product/123).

You can also choose to put a wildcard ´*´ as path to match any url. This could be a way to have a catch-all route, to display a 404-route or something similar.

After determining what element-route should be put in the outlet, you can put an element-attribute on it. This is a string with the element name of the element you want rendered. This will typically be a customElement, but it doesn’t have to be. If you want the element-configuration to be loaded asynchronously (for performance reasons) you can use the import-attribute to point to a file that should be downloaded and executed before rendering the element.

If for a given route, you don’t want (or don’t have) a customElement, you can leave the element-attribute out, and put a template-element inside the element-route.

The last feature is the redirect-attribute, which simply changes the url to its value whenever that element-route’s path is matching.

You can see a demo (https://elementrouter.firebaseapp.com), find the source on github (ttps://github.com/filipbech/element-router), or download from npm (https://www.npmjs.com/package/element-router). Feel free to ask questions or contribute otherwise.

I hope this will be helpful for someone, or at least be a source of inspiration into whats possible with webcomponents today. Remember this was all done in less than 1kb javascript (minified and gzipped of course).