router
router copied to clipboard
The extensible client-side router for Alpine.js v3
Pinecone Router
The extendable client-side router for Alpine.js.
Compatibility
Currently works with Alpine.js v2 only
About
An easy to use but feature-packed client-side router for use with Alpine.js.
It can be used to:
- Handle routes & process route variables.
- Use magic helper
$router
helper to display elements dynamically etc. inside all Alpine.js Components. - Many more using middlewares!.
Features:
- :smile: Easy and familiar syntax well integrated with Alpine.js.
-
- The router is an Alpine component, handlers and settings are set in its data.
- :link: Automatically dispatch relative links and handle them.
- :hash: Hash routing.
- :heavy_plus_sign: Extendable using tiny Middlewares! 🪜.
- :sparkles: Magic $router helper to access current route, params, redirect, ect. from all alpine components!
- :gear: Easily configurable through settings!
- Typescript definitions
Demo: Pinecone example, (source code).
Installation
Check the CHANGELOG before updates.
CDN
Include the following <script>
tag in the <head>
of your document, before Alpine.js:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.umd.js"></script>
ES6 Module:
import 'https://cdn.jsdelivr.net/npm/[email protected]/dist/index.module.js';
NPM
npm install pinecone-router
// load pinecone router
import 'pinecone-router';
// then load alpine.js
import 'alpinejs';
Important: This must be added before loading Alpine.js.
Usage
Demo & Usage Example
Handle routes
- Create an Alpine.js component with an empty
x-router
attribute. - Declare routes by creating a template tag with
x-route
andx-handler
attributes.
<div x-data="router()" x-router>
<!-- You can pass in a function name -->
<template x-route="/" x-handler="home"></template>
<!-- Or an anonymous/arrow function -->
<template x-route="/home" x-handler="(ctx) => ctx.redirect('/')"></template>
<!-- Or even an array of multiple function names/anonymous functions! -->
<template x-route="/hello/:name" x-handler="[checkName, hello]"></template>
<!-- 404 handler -->
<template x-route="notfound" x-handler="notfound"></template>
</div>
<div id="app"></div>
Important: There can only be one router in the page!
The javascript:
can also be embedded inside
x-data
.
function router() {
return {
main(context) {
document.querySelector('#app').innerHTML = `<h1>Home</h1>`;
},
checkName(context) {
// if the name is "home" go to the home page.
if (context.params.name.toLowerCase() == 'home') {
// redirecting is done by returning the context.redirect method.
return context.redirect('/');
}
},
hello(context) {
document.querySelector(
'#app'
).innerHTML = `<h1>Hello, ${context.params.name}</h1>`;
},
notfound(context) {
document.querySelector('#app').innerHTML = `<h1>Not Found</h1>`;
},
};
}
Context Object
The handler takes a context
argument which consists of:
-
context.route (/path/:var) The route set with
x-route
. - context.path (/path/something) The path visited by the client.
- context.params ({var: something}) Object that contains route parameters if any.
- context.hash hash fragment without the #
- context.query search query without the ?
- context.redirect(path: string) function that allow you to redirect to another page.
-
-
Important: usage within x-handler:
return context.redirect('/path');
-
Important: usage within x-handler:
Route matching
Parameters can be made optional by adding a ?, or turned into a wildcard match by adding * (zero or more characters) or + (one or more characters):
<template x-route="/b/:id" x-handler="..."></template>
<template x-route="/a/:optional?/:params?" x-handler="..."></template>
<template x-route="/c/:remaining_path*" x-handler="..."></template>
<template x-route="/d/:remaining_path+" x-handler="..."></template>
Borrowed from Preact Router
Redirecting
It can be done many ways! here's how:
From an Alpine component:
- use
$router
magic helper:$router.redirect(path)
. -
- example:
@click="$router.redirect(path)"
- example:
Redirecting from the handler:
To redirect from inside a handler function return the context's redirect
method:
handler(context) {
...
return context.redirect(path)
}
Important: inside the handler you must return the
context.redirect()
function.
Middlewares
Pinecone Router is extendable through middlewares!
Official Middlewares
-
Render views: manually set the view for each route and have it rendered!
-
Display server rendered pages: automatically load server-rendered pages with preloading (like Turbolinks) WIP!
Create your own middlewares using this template!
Settings:
To override settings simply add a settings
parameter to your router component's data.
Note: you don't have to specify all, just the ones you want to override.
function router() {
return {
// configuration
settings: {
/**
* @type {boolean}
* @summary enable hash routing
*/
hash: false,
/**
* @type {string}
* @summary The base path of the site, for example /blog
* Note: do not use with using hash routing!
*/
basePath: '/',
}
// handlers
...
};
}
Bypass link handling
Adding a native
attribute to a link will prevent Pinecone Router from handling it:
<a href="/foo" native>Foo</a>
Global Context
You can access current path's context from alpine components use $router magic helper or from anywhere in your javascript by accessing window.PineconeRouter.currentContext
.
Magic Helper
To make it easier to access the current context from anywhere, you can use the $router
magic helper:
Usage:
Refer to global context.
$router.params.name
, $router.redirect(path)
, $router.hash
, etc.
Loading bar
You can easily use nProgress.
Tip: if you're going to fetch
views, you can use this middleware which provide loading events
Advanced
Show
Adding & Removing routes with Javascript
you can add routes & remove them anytime using Javascript.
Adding a route:
window.PineconeRouter.add(path, handlers);
- path: string, the route's path.
- handlers: array of functions, the handlers of the route.
Removing a route:
window.PineconeRouter.remove(path);
- path: string, the path of the route you want to remove.
Navigating from Javascript:
To navigate to another page from javascript you can:
window.PineconeRouter.navigate(path);
Browser Support
Supports same versions supported by Alpine.js by default, including IE11.
dist/index.modern
is provided if you want to only support modern browsers with es6+ support.
full list
and_chr 89, and_ff 86, and_qq 10.4, and_uc 12.12, android 89, baidu 7.12, chrome 90, chrome 89, chrome 88, chrome 87, edge 90, edge 89, edge 88, firefox 87, firefox 86, firefox 78, ie 11, ios_saf 14.0-14.5, ios_saf 13.4-13.7, kaios 2.5, op_mini all, op_mob 62, opera 73, opera 72, safari 14, safari 13.1, samsung 13.0, samsung 12.0Contributing:
Please refer to CONTRIBUTING.md
Credits
This library uses modified chunks of code from this tutorial & from page.js. The parts used are specified in source comments.
Acknowledgment
@KevinBatdorf for many ideas and early feedback!
Disclaimer: Not affiliated with the Alpine.js team, developed independently.
Versioning
This projects follow the Semantic Versioning guidelines.
License
Copyright (c) 2021 Rafik El Hadi Houari and contributors
Licensed under the MIT license, see LICENSE.md for details.
Pinecone Router Logo by Rafik El Hadi Houari is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Code from Page.js is licensed under the MIT License. Copyright (c) 2012 TJ Holowaychuk [email protected]
Code from Simple-javascript-router tutorial is licensed under the MIT License. Copyright (c) 2021 Vijit Ail (https://github.com/vijitail).
Route matching function from Preact Router is licensed under the MIT License. Copyright (c) 2015 Jason Miller