Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Define a series of routes as a stream in order to consolidate route logic outside of the remit of individual endpoints
import m from 'mithril'
import stream from 'mithril/stream/stream'
export default function routeStream(
defaultRoute = '/',
routes = ['/:path...']
const routeStream = stream()
routes.reduce((map, route) => {
map[route] = {
return map
}, {})
return routeStream

m route stream

Mithril's route API is predicated on the notion that all logic and view concerns are specific to a given route endpoint. In any significant application, this leads to a lot of flaky code duplication: most views share a lot of markup; some persistent application logic is route-agnostic; some logic needs to be run on every route. In these scenarios it makes more sense to treat the route as a data source, and mount a single top level component with a consolidated lifecycle that is guaranteed to have access to all route data.

mRouteStream offers an interface concerned solely with the business of routing, allowing you to provide a list of routes and handle Mithril view logic separately. The return value of mRouteStream is a stream which emits an array that matches the signature of onmatch.


const route = mRouteStream(defaultRoute, routes)
Argument Type Required Default Description
defaultRoute String No '/' The default route - maps to the second argument of Mithril's m.route
routes Array No [':path...'] The routes, without endpoint mapping - the equivalent of running Object.keys on the third argument of Mithril's m.route
returns Stream A stream that emits an array conforming to Mithril's RouteResolver onmatch signature


const route = mRouteStream( '/', [

m.mount(document.body, {
    // Centralised route parsing logic[args, requestedPath]) => {
      // Bind route data to state
      Object.assign(this, {args, requestedPath})
      // Flag a route-based redraw
      this.routing = true

  // Centralised route-based lifecycle logic
    // Infer route-based redraw
      scrollTo(0, 0)
      this.routing = false

  // Single comprehensive view
  view : vnode =>
    ? m(NotFound, requestedPath) // High-level fork
    : m(Layout, // Common elements defined once rather than copy-pasted across route endpoints
        m(Header, vnode.state ), // Passing down route data for high-level components
        ? m(Page, vnode.state)
        ? m(Post, Object.assign(
            // Route data can be abstracted at any point
            { editing : /edit$/.test(vnode.state.requestedPath) },
if(typeof require == 'function'){
var m = require('mithril')
var stream = require('mithril/stream/stream')
function routeStream(defaultRoute, routes){
var routeStream = stream()
defaultRoute || '/',
(routes || ['/:path...']).reduce(function(map, route){
map[route] = {
return map
}, {})
return routeStream
if(typeof module == 'object')
module.exports = routeStream
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment