Close
Written by
Marta Dycjan

Marta Dycjan

Router.js vs Crossroads.js: Which One Do You Need?

Why would you need JavaScript routing?

Building small browser’s application with Knockout.js library is quite easy and probably the core functionality of this library is sufficient. Usually there is no need for additional frameworks unless your application gets bigger and more complex. Then, you probably want to build it as a Single Page App (SPA). As shown below, typically SPA is based on three pillars: modularization, binding and routing. In my case application already had binding (Knockout.js) and modularization (RequireJS), so we just needed routing system that would help track application states easily and, therefore, keep our complex UI clean and tidy. As always, when it goes to javascript, there is a wide range of the routing libraries to choose from.

spaimg

Router.js vs Crossroads.js: Which One Do You Need?

There are many open source JS routing frameworks – Crossroads.js, Sammy.js, Pager.js or Router.js to name a few. You may wonder which one to use. I looked briefly at the two.

Router.js is much more advanced framework and on the first glance it may seem better. If you look for a framework on the top of which you could build a complex wizard mechanism with validation rules or just general error handling – it may be a great solution. However, it is worth to consider whether requirements it imposes on the implementation and integration with the existing system are not too time-consuming and whether the impact on project’s architecture is not too deep. But when only base functionality of the routing system is needed (i.e. route handling), Crossroads.js is also a valid option, especially in a scenario when you already have an existing application and you don’t need to create it from scratch, but only extend it with a new module. In case when it meets project’s requirements, Crossroads.js simplicity and ease of integration are huge advantages.

Crossroads.js

Using Crossroads.js is really straightforward. You do not need to dig deep into the documentation to write simple routing configuration. You just need to pass a rule and a handler function for it. The rule can be both, string and regular expression pattern.

You may configure each route separately:

crossroads.addRoute(/^\/news\/([0-9]+)$/, , function(id){
  console.log(id);
  // handle state for news with id 'id'
});

crossroads.addRoute('/news/', function(){
  console.log('news');
  // handle state for news summary
});

or have one generic handler for all routes:

crossroads.addRoute('/news/{id}');
crossroads.addRoute('/news/');
crossroads.routed.add(function(request, data){
  console.log(request);
  console.log(data.route +' - '+ data.params);
  // handle data.route state
});

Besides that you can also define callback function which is executed when no route is matched:

crossroads.bypassed.add(function(request){
  console.log(request);
});

If you are up-to-date with Knockout.js, you probably have heard about the components – new significant feature released in version 3.2.0. It is really easy to integrate it with Crossroads.js routing – handling routing change may result in generation of the matching component.

Router.js

Router.js not only gives you a handling mechanism, but a lot more. You get out-of-the-box advanced framework for managing page states. But, it also means that you will need some time to learn how to use it.

Basically, handling new route means creating proper transition callbacks: one for creating model data and one for rendering view with this data.

router.map(function(match) {
  match('/news/:id').to('showNews');
});

var myHandlers = {};
myHandlers.showNews = {
  model: function(params) {
    // create model
    return {};
  },

  setup: function(news) {
    // news parameter is newly created model 
    // render a template with newly created model - news  
  }
};

router.getHandler = function(name) {
  return myHandlers[name];
};

Not only model and setup callbacks are invoked in a route handling process, but a lot more happens. Router.js exposes many callbacks during cycle of routing like: beforeModel, afterModel, exit (when route is no longer active) or enter (when route becomes active).

Another nice feature is nested routing. It means that each part of routing can have its own handler. It can be helpful in implementing master-detail view.

router.map(function(match) {
  match('/news').to('news', function(match) {
    match('/').to('newsIndex');
    match('/:id').to('showNews');
  });
});

One more interesting functionality is built-in events. Those can be used for customizing transition behaviour, for example: willTransition can be used for aborting or redirecting current transition and error event for error handling.

Finally worth mentioning is that Router.js is a part of widely known Ember.js framework.

A word of caution!

Both Crossroads.js and Routing.js follow the Single Responsibility Principle (SRP). It means that they just parse url input and decide how to handle it. To listen to hash state changes in a browser and notify a routing library about those changes, you need another library, for example you might use hasher.js.

Share this post on

Leave a Reply

Required fields are marked *

Read next

How to create a nice presentation? Colours!

If you have read my previous post probablly you remember I have mentioned about art skills of UI Developers. It is a one of reason why many collegous ask me for a help to find a nice set of colours and face fonts for their presentations. Sounds familiar? If you also has this kind of problem from time to time […]

Read more