TLDR: Ember.js implicitly creates an index
child route for you when you nest
under a route
This appears to be not so well known on the Ember community, and I don’t think it’s documented anywhere. I should have a go at clarifying this on the official docs (through a pull request on the project), but for the moment I’ll dump it here.
This is how it works. Say you declare a route in router.js
:
1this.route('lines');
This declaration will get you a route, called lines
. Nothing new here. Now
let’s declare the same route, but with nesting:
1this.route('lines', function(){});
This is subtly different. We added nesting but left it empty, so there’s no
reason to think that the result would be any different. However, there is indeed
a difference. This will get you not one but two routes: lines
and
lines.index
. Specifically, it’s the same as declaring the following:
This actually makes a lot of sense. If we think as lines
as a “trunk” route
and lines.index
as a “leaf”, it turns out that trunk routes cannot be
“landed”. These routes have an outlet
that needs to be filled out. If we try
to land on a trunk route, for example using transitionTo
, Ember will redirect
us to the index
leaf route under them, and the outlet will get its content. In
other words, these two transitions are equivalent, assuming that lines
is a
route with nesting:
These implicit index
routes are implemented with an empty route module and an
empty template. We don’t notice any of this, but we can verify it by using the
Ember Inspector, where we can see these routes, along with loading
and error
subroutes:

Implicit routes showing up on the Ember Inspector
This can go several levels deep. If we explicitly declare an index
route with
nesting, Ember will declare yet another index
under it:
If we try to transition to lines
, Ember will take us to lines.index
and then
in turn to lines.index.index
. This can go on for as long as necessary, until a
leaf route is found where we can land safely.