Redirect to a "default" subroute

Let’s say we have a URL structure as follows:

- /user
- /user/profile
- /user/friends
- /user/preferences

And we want to define a “default” nested route where to redirect when a visitor reaches /user.

In our example we want to redirect to /user/profile anytime /user is hit.

Easy, right? We know we can handle a redirect in a route using transitionTo(). We put that in that “user” route and call it a day.

// app/routes/user.js

export default Ember.Route.extend({
  beforeModel() {
    this.transitionTo('user.profile');
  }
});

It does work. But when we visit /user/friends – and we also get redirected to the profile page!

Why? Because to get to /user/friends, Ember calls all routes in the chain ((application) > user > user.friends). By the time it hit user, it already redirected to user.profile.

Hmmm. Perhaps we can decide whether we redirect or not based on transition.targetName?

That may be possible, but let me show you the proper way.

The secret route

Our URLs above have this route structure:

- user (/user URL)
  - user.profile (/user/profile URL)
  - user.friends (/user/friends URL)
  - user.preferences (/user/preferences URL)

We can see explore routes in the Routes tab of the Ember Inspector. There we will see additional routes such as user.loading and user.error that we will leave for another episode!

There is one (implicit?) route that is not mentioned, but that will solve our problem. The user.index route.

- user (/user URL)
  - user.index (/user/ URL)
  - user.profile (/user/profile URL)
  - user.friends (/user/friends URL)
  - user.preferences (/user/preferences URL)

This route will activate when we visit the /user URL.

Since user.index is nobody’s parent we can safely implement the redirect there:

// app/routes/user/index.js

export default Ember.Route.extend({
  beforeModel() {
    this.replaceWith('user.profile');
  }
});

Note that we now used replaceWith instead of transitionTo. It is identical to transitionTo except that it won’t add a new browser history entry.

As Ember will go through all route segments, this same technique is useful when a resource intensive page lives at the /user URL. By moving it to the user.index route, we avoid having to load this heavy content when accessing subroutes such as user.profile or user.friends directly.

Enjoyed this article? Don't miss my next one!

Leave me your e-mail for content that will help you master Ember:

Do you want to master Ember fast?

Leave me your e-mail for helpful updates delivered straight to your inbox.

(A few e-mails per month. No BS. Unsubscribe anytime!)