TypeScript icon, indicating that this package has built-in type declarations

    1.0.4 • Public • Published

    GitHub tag (latest by date) npm bundle size Downloads from JSDelivr npm David Changelog Sponsor

    Pinecone Router

    The extendable client-side router for Alpine.js.


    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!.


    • 😄 Easy and familiar syntax well integrated with Alpine.js.
      • The router is an Alpine component, handlers and settings are set in its data.
    • 🔗 Automatically dispatch relative links and handle them.
    • #️⃣ Hash routing.
    • Extendable using tiny Middlewares! 🪜.
    • Magic $router helper to access current route, params, redirect, ect. from all alpine components!
    • ⚙️ Easily configurable through settings!
    • Typescript definitions

    Demo: Pinecone example, (source code).


    Check the CHANGELOG before updates.


    Include the following <script> tag in the <head> of your document, before Alpine.js:

    <script src=""></script>

    ES6 Module:

    import '';


    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.


    Demo & Usage Example

    Handle routes

    1. Create an Alpine.js component with an empty x-router attribute.
    2. Declare routes by creating a template tag with x-route and x-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 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 ( == 'home') {
    				// redirecting is done by returning the context.redirect method.
    				return context.redirect('/');
    		hello(context) {
    			).innerHTML = `<h1>Hello, ${}</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');

    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="/c/:remaining_path*" x-handler="..."></template>
    <template x-route="/d/:remaining_path+" x-handler="..."></template>

    Borrowed from Preact Router


    It can be done many ways! here's how:

    From an Alpine component:

    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.


    Pinecone Router is extendable through middlewares!

    Official Middlewares

    Create your own middlewares using this template!


    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.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

    Demo Source



    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:

    • path: string, the path of the route you want to remove.

    Navigating from Javascript:

    To navigate to another page from javascript you can:


    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.0


    Please refer to

    Sponsor ♥️

    If you find this helpful and would like to support my work you can Donate with Coinbase

    Any amount would be appreciated ^^


    This library uses modified chunks of code from this tutorial & from page.js. The parts used are specified in source comments.


    @KevinBatdorf for many ideas and early feedback!

    Disclaimer: Not affiliated with the Alpine.js team, developed independently.


    This projects follow the Semantic Versioning guidelines.


    Copyright (c) 2021 Rafik El Hadi Houari and contributors

    Licensed under the MIT license, see for details.

    Creative Commons License
    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

    Code from Simple-javascript-router tutorial is licensed under the MIT License. Copyright (c) 2021 Vijit Ail (

    Route matching function from Preact Router is licensed under the MIT License. Copyright (c) 2015 Jason Miller


    npm i pinecone-router

    DownloadsWeekly Downloads






    Unpacked Size

    532 kB

    Total Files


    Last publish


    • rehhouari