Mithril JS Route Scrolling

Restoring expected scroll-to-top behavior when a route changes in Mithril
Created: 2018-01-25

It used to be that old Mithril (v.0.2.x) would automatically scroll to the top of the page after any route change. This was expected and desired behavior 99% of the time. Unfortunately, it was accomplished with a hard-coded call to window.scrollTo(0,0) which you could not disable. I had to keep my own 'hacked' copy of Mithril with the scrollTo() commented out to circumvent this behavior (ugh!).

Others also occasionally ran into problems with this. See GitHub issues:

Wisely, Mithril v1.x has opted to drop the forced scrollTo(). Sadly, instead of making the behavior optional, it has been removed entirely!

See Github issue:

Argh!

The solution

Fortunately, it is very easy to wrap the two routing functions, set() and get() so that they restore the original behavior.

var m.route.setOrig = m.route.set;
m.route.set = function(path, data, options){
	m.route.setOrig(path, data, options);
	window.scrollTo(0,0);
}

var m.route.linkOrig = m.route.link;
m.route.link = function(vnode){
	m.route.linkOrig(vnode);
	window.scrollTo(0,0);
}

I’ve tested the wrappers with Firefox and Chrome.

The nice thing about this solution is that you have complete control over this functionality. You can, for example, have some routes which scroll and some which don’t (call m.route.setOrig() instead).

Obviously these can be placed anywhere after the Mithril library has been loaded. I placed these wrappers right above my call to m.route(document.body, MyComponent) so that all of my routing 'stuff' stays logically grouped together.