This package has been deprecated

Author message:

Renamed to pinecone-router, please install pinecone-router instead.

alpinejs-router

0.0.9 • Public • Published

GitHub tag (latest by date) GitHub file size in bytes Downloads from Jsdelivr Github Downloads from Jsdelivr NPM npm Changelog

Alpine Router

The simple client-side router for Alpine.js.

About

An easy to use but feature-packed client-router for use with Alpine.js. It can be used to handle routes manually, render specific views, and automatically render server-rendered pages-with preload!

Features:

  • Easy and familiar syntax well integrated with Alpine.js.
  • Automatically dispatch relative links and handle them (optional).
  • Hash routing!
  • Display server rendered pages: automatically load server-rendered pages with preloading (like turbolinks, optional)
  • Render views: manually set the view for each route and have it rendered! (optional)
  • Easily tweakable through many Settings!
  • Magic helper $router to access current route, props, redirect, ect. from alpine components!

Installation

It works but not ready for production yet, needs reviewing and more testing, help welcome!

CDN

Include the following <script> tag in the <head> of your document:

<script src="https://cdn.jsdelivr.net/npm/alpinejs-router@0.0.9/dist/complete.umd.js"></script>

ES6 Module:

import 'https://cdn.jsdelivr.net/npm/alpinejs-router@0.0.9/dist/complete.umd.js';

NPM

npm install alpinejs-router
import 'alpinejs-router';
import 'alpinejs';

Important: This must be added before loading Alpine.js.

Note: Smaller, feature-specific builds will be available soon ^^

Usage

Handle routes

  • Create an Alpine component with the x-router attribute.
  • Declare routes by creating a template tag with x-route and x-handler attributes.
  • The x-handler must be a method of the router component.
<div x-data="handle()" x-router>
	<template x-route="/hello/:name" x-handler="hello"></template>
	<template x-route="/" x-handler="main"></template>
	<template x-route="notfound" x-handler="notfound"></template>
</div>

Important: There can only be one router in the page!

function handle() {
	return {
		main() {
			console.log('main');
		},
		hello(context) {
			console.log('hello,', context.props.name);
		},
		notfound(context) {
			console.error(context.path + ' is not found');
		},
	};
}

Context Object

The handler takes context which consist of:

  • context.route (/path/:var)
  • context.path (/path/something)
  • context.props ({var: something})
  • context.hash (hash fragment without the #)
  • context.query (search query without the ?)
  • context.go(path: string) function that allow you to redirect to another page.
    • Important usage witihn x-handler: return context.go('/path');

Hash routing

You may use hash routing by simply adding x-hash attribute to the router component:

<div x-data="handle()" x-router x-hash>...</div>

Page rendering

You can use Alpine Router to render server generated pages without reloads!

<div x-data x-router x-render></div>

By default this will fetch the whole page and replaces the <body> content. To use antoher element instead, set its selector: x-render="#content".

Handling routes while using x-render

You can also handle routes while all pages render normally!

<div x-data="handle()" x-router x-render>
	<template x-route="/hello/:name" x-handler="hello"></template>
</div>

Note: The routes will be handled before the page is rendered.

Notfound and specifying routes

By default, 404 pages are left to the server to handle. However, if you'd like to specify the routes allowed, you can do it like this:

<div x-data="handle()" x-router x-render>
	<template x-route="/"></template>
	<template x-route="/hello/:name"></template>
	<template x-route="notfound" x-handler="notfound"></template>
</div>

As you see, the handler is optional on routes as the page will be rendered regardless, but you can add it if you need it.

Notes: By default routes not found will be pushed to history. That can be prevented by setting AlpineRouter.settings.pushNotfoundToHistory = false.

Views rendering

Unlike page rendering, you get to specify the view for each route.

  • Routes can share views.
  • View are simply html files.
  • Can specify selector as well.
<div x-data x-router x-views="#content">
	<template x-route="/" x-view="/home.html"></template>
	<template x-route="/hello/:name" x-view="/hello.html"></template>
	<template x-route="notfound" x-view="/404.html"></template>
</div>

Notes: :

  • A view is required for each route.
  • You can cache views if they're static and not dynamically generated by adding x-static to the router:
    • <div x-data x-router x-views x-static>
  • You can set the selector by specifying it x-views. leaving it empty will default to '#content'.
  • You can also handle routes while using views
    • Note: The routes will be handled before the page is rendered.

Authorization

If you'd like to make checks before actually displaying a view/page, using authentication/authorization etc, you can make your checks in the handler. Then within the handler, if you need to redirect the user to another page simply return context.go('/another/page') this way it'll prevent the views from rendering and go to the other page directly.

Example:

The route you'd like to authorize: In this example the user will only be allowed to edit their own profile

<div x-data="router()" x-router x-views>
...
<template
	x-route="/profile/:username/edit"
	x-handler="editprofile"
	x-view="/editprofile.html"
></template>
<template
	x-route="/unauthorized"
	x-view="/unauthorized.html"
></template>
...

The handler: (auth is a placeholder name, replace it with your own auth provider methods)

editprofile(context) {
	if (context.props.username != auth.username) {
		return context.go('/unauthorized');
	}
}

This works for when using both x-views or x-render

Tip! To access the current context (props etc) from within the views, use the $router Magic Helper or window.AlpineRouter.currentContext.

Important: Make sure the view don't have an Alpine Router component in them! Keep the router component outside of the specified selector.

Can't use body as the selector to avoid that issue.

Redirecting

You can navigate to another page by calling AlpineRouter.navigate(path) with path being the path you want to navigate to.

Settings:

There are a few settings you may tweak for your liking.

To access or set them from javascript, use AlpineRouter.settings.name = value.
with name being the name of the settings as seen bellow:

name default description
interceptLinks true whether or not to intercept links
pushNotfoundToHistory true whether or not paths that are not found should be pushed to history
render.preload true whether to preload pages on mouse over links
render.preloadtime 200 time to wait to preload pages on mouse over links
views.static false views are not dynamically generated, this will cache views for later use.

Base path: is set with the x-base attribute. Trailing slash: x-slash="add" or empty to force adding trailing slash or x-slash="remove" to force removing them.

Events:

Alpine Router dispatch these events:

name recipient description
routerloaded window when the router and routes are initialized
loadstart window when the page start loading
loadend window when the page loading ends

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.AlpineRouter.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.props.name, $router.go(path), $router.hash, etc.

Contributing:

Please refer to CONTRIBUTING.md

Credits

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

Acknowledgment

@KevinBatdorf for the page rendering idea and early feedback!

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.

Code from Page.js is licenced under the MIT License. Copyright (c) 2012 TJ Holowaychuk tj@vision-media.ca

Code from Simple-javascript-router tutorial is licenced under the MIT License. Copyright (c) 2021 Vijit Ail (https://github.com/vijitail).

Package Sidebar

Install

npm i alpinejs-router

Weekly Downloads

1

Version

0.0.9

License

MIT

Unpacked Size

235 kB

Total Files

20

Last publish

Collaborators

  • rehhouari