Here at Dollar Shave Club, we rely heavily on open-source technologies. We chose Ember.js as our front end framework to build our web experience.

By design, Ember maintains scroll position when transitioning between routes. This makes sense for typical single page applications (SPAs), as SPAs tend to be rendered with nested views. If a nested view is 1000px down the page, when you enter that nested route, you would want to still be 1000px down the page.

However, our design calls for rendering pages in a non-nested fashion. The default Ember behavior of maintaining scroll position is no longer the right user experience (UX).

Default ember scroll behavior

As a result, one of the first pieces of Ember code written here at Dollar Shave Club is a way to scroll the user to the top of the page on route transition.

Unfortunately, this presents a new UX problem. While scroll-to-top is good UX for entering a new route, a user would expect to maintain scroll position when going back and forward in the browser.

To solve this problem, we created a scrollMap to store scroll states on willTransition, a hook that gets called whenever a user leaves a route. In the didTransition hook, we check to see if the transition was triggered by a browser history event (popstate event). If a popstate is detected, the user is sent to the scroll position in the scrollMap instead of the top.

ember-router-scroll behavior

Check it out here: ember-router-scroll.