Skipping History Entries in Ember Transitions

November 01, 2013

Occasionally you’ll redirect a user in Ember silently based on some condition instead of them taking an action (like clicking a link). In that case, you don’t want to pollute their browser history, as hitting ‘back’ button would kick them into a loop.

This is frustratingly common in applications that manipulate the history API and can cause confusion for the user.

Ember has a good method for dealing with this. For those “silent” transitions that will trigger based on a condition, use replaceRoute instead of transitionToRoute.

Here’s an example route that demonstrates how to use it. This assumes that you have Post that has a draft attribute telling the application to only show it to authenticated users.

// A simple Ember.Route for a Post. In this case, the Post has a
// draft boolean that protects it from the public and requires
// authentication. We need to redirect a user there without polluting
// their history so "back" still works.
//
App.PostRoute = Ember.Route.extend({
  model: function(params) {
      return App.Post.find(params.id) // return a Post for /post/:id
  },

  setupController: function(controller, post) {
    if (post.draft === true) {
      // In the case of a draft, we want to redirect to a log-in
      // route to authenticate the user, sending them to /authenticate
      controller.replaceRoute("authenticate");
    }
    // Otherwise, continue as normal and load the post
    controller.set('model', post);
  }
});

The replaceRoute method won’t create a history entry, avoiding a redirect loop.


The following GitHub users contributed to this post. If you notice a typo, edits are appreciated.

Loading authors from GitHub...

There are more posts on the index page.