How to handle 'no route matched' in Ember.js and show 404 page?

Solution 1:

App.Router.map(function() {
  //set up all of your known routes, and then...
  this.route("fourOhFour", { path: "*path"});
});

.. where you have your FourOhFourRoute defined to show the "no route found" message of your choosing. You will be able to access the originally requested path in the fourOhFour route as the path parameter.

EDIT: just for clarity -- this answer came after the others were reported not to work anymore.

EDIT 2: I've updated the answer to reflect Yehuda Katz's comment (if I have it wrong, please LMK).

Solution 2:

Here is an example:

I define the last route in my router using a wildcard route see: http://emberjs.com/guides/routing/defining-your-routes/#toc_wildcard-globbing-routes

I have a /not-found route, see last route defined in my router /*path to catch any text string, see: https://github.com/pixelhandler/blog/blob/master/client/app/router.js#L19

Router.map(function () {
  this.route('about');
  this.resource('posts', function () {
    this.resource('post', { path: ':post_slug' });
  });
  this.resource('admin', function () {
    this.route('create');
    this.route('edit', { path: ':edit_id' });
  });
  this.route('not-found', { path: '/*path' });
});

That route does a redirect to /not-found, see: https://github.com/pixelhandler/blog/blob/master/client/app/routes/not-found.js

import Ember from 'ember';
export default Ember.Route.extend({
  redirect: function () {
    var url = this.router.location.formatURL('/not-found');
    if (window.location.pathname !== url) {
      this.transitionTo('/not-found');
    }
  }
});

Also any route having a hook (e.g. model, beforeModel, afterModel) that results in a rejected promise, can use the error action to transition to the 404.

actions: {
  error: function (error) {
    Ember.Logger.error(error);
    this.transitionTo('/not-found');
  }
}

Which renders a not-found template, see: https://github.com/pixelhandler/blog/blob/master/client/app/templates/not-found.hbs

<h1>404 Not Found</h1>
<p>
  Perhaps you have a link that has changed, see {{#link-to 'posts'}}Archives{{/link-to}}.
</p>

Here is my 404 page: http://pixelhandler.com/not-found

Solution 3:

You could try adding a catch-all route at the end of your router:

App.Router.map(function() {
  this.resource('post', ...);
  this.resource('user', ...);
  this.route('catchAll', { path: '/*' });
});

App.CatchAllRoute = ...

Solution 4:

In Ember 2.x

Inside the App.Router.map function, put code below the the end of the callback function.

this.route('your_handler_route_name', { path: '/*path' });

Now every route does NOT catche by the previous defined routes will be catched by your_handler_route_name route.