A minimal WIP route handling framework on top of choo
JavaScript
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.editorconfig
.eslintrc.yaml
.gitignore
LICENSE
README.md
index.js
model.js
package.json
utils.js

README.md

choo-routehandler

This is a small route handling framework on top of Choo. Beware it's a work in progress and likely to change!!

The core feature of this framework is that it provides a function for wrapping your route handlers, mitigating the need for writing boilerplate code. It requires three arguments: view, loader and layout. You can also pass an options object as the fourth argument.

view
Either a function, for rendering the view corresponding to the route, or a module containing at least a function render fulfilling the aforementioned responsibility, optionally a function loadData for loading data pertaining to the route before rendering it and optionally a function or attribute pageTitle for defining a route's page title. The loadData function should return a promise resolving to an object to patch Choo state with.
loader
An argument free function that should return a DOM element representing a loading screen.
layout
A function representing the layout of the view, that should take four arguments, the rendered view, state, prev and send, and return a DOM element.
opts
An object providing options to the route handler. The following options are supported:
  • requiresLogin: Configure whether the route requires the user to be logged in.
  • isUserLoggedIn: A function taking state as its argument, returning whether the user is logged in or not.
  • loginUrl: The URL to redirect to if the route requires login and user hasn't yet been logged in.

Route Rendering

The route handler wrapper renders the view for your route inside a container element, #route-container, possessing an attribute called data-route, which encodes the current route and query string. It also registers a callback via a MutationObserver that triggers when said attribute changes, in order to react as the rendered route changes. The reaction is implemented as a Choo effect handleRouteLoadedIntoDom, which gets defined in the model part of the framework.

The behaviour of the route handler is to, once it detects that the currently rendered route changes (including its query string), go through a standard procedure in order to render the corresponding view, depending on whether or not there is a data loading hook for the route:

With a Data Loading Hook

  1. Invoke the loadData hook and render the loading view.
  2. Once the loadData promise resolves, merge the resulting state subgraph into the Choo state graph. Then call the render hook in order to render the view corresponding to the route.

Without a Data Loading Hook

Just render the view corresponding to the route.

The Model

The model, defined in the model.js file of the package (import as e.g. require('@arve.knudsen/choo-routehandler/model')), defines state/effects/reducers required by the framework.

Example

const routeHandler = require('@arve.knudsen/choo-routehandler')
const routeHandlerModel = require('@arve.knudsen/choo-routehandler/model')
const app = require('choo')

const loading = require('./loading')
const layout = require('./layout')

app.model({
  state: {...}
})
routeHandlerModel(app)

app.router({default: '/404',}, [
  ['/404', routeHandler(notFoundView, loading, layout),],
  ['/', routeHandler(mainView, loading, layout),],
])