AngularJS and Handling 404 Errors

Ryan Shea picture Ryan Shea · Jul 8, 2013 · Viewed 39k times · Source

What is the best way to serve up proper 404's with an AngularJS app?

A little background: I'm building an Angular app and have opted to use

$locationProvider.html5Mode(true);

because I want the URLs to appear natural (and indistinguishable from a multi-page "traditional" web app).

On the server side (a simple Python Flask app), I have a catch-all handler that redirects everything to the angular app:

@app.route('/', defaults={'path': ''})
@app.route('/<path>')
def index(path):
    return make_response(open('Ang/templates/index.html').read())

Now, I'm trying to figure out what to do with 404 errors. Most of the Angular apps I've seen do the following:

.otherwise({ redirectTo: '/' })

which means that there is no way they can serve up a proper 404.

However, I would much rather return a proper 404, with a 404 status code (mainly for SEO purposes).

What is the best way to handle 404s with Angular? Should I not worry about it and stick with a catch-all? Or should I remove the catch-all and serve up proper 404's on the server side?

edited for clarity

Answer

Miguel picture Miguel · Jul 8, 2013

I think you are confusing Flask routes with Angular routes.

The 404 error code is part of the HTTP protocol. A web server uses it as a response to a client when the requested URL is not known by the server. Because you put a catch-all in your Flask server you will never get a 404, Flask will invoke your view function for any URLs that you type in the address bar. In my opinion you should not have a catch-all and just let Flask respond with 404 when the user types an invalid URL in the address bar, there is nothing wrong with that. Flask even allows you to send a custom page when a 404 code is returned, so you can make the error page look like the rest of your site.

On the Angular side, there is really no HTTP transaction because all the routing internal to the application happens in the client without the server even knowing. This may be part of your confusion, Angular links are handled entirely in the client without any requests made to the server even in html5mode, so there is no concept of a 404 error in this context, simply because there is no server involvement. An Angular link that sends you to an unknown route will just fall into the otherwise clause. The proper thing to do here is to either show an error message (if the user needs to know about this condition and can do something about it) or just ignore the unknown route, as the redirectTo: '/' does.

This does not seem to be your case, but if in addition to serving the Angular application your server implemented an API that Angular can use while it runs, then Angular could get a 404 from Flask if it made an asynchronous request to this API using an invalid URL. But you would not want to show a 404 error page to the user if that happened, since the request was internal to the application and not triggered by the user directly.

I hope this helps clarify the situation!