How to have Express routing work with Angular routing with HTML5 style URLs?

All we need is an easy explanation of the problem, so here it is.

I would like to make an AngularJS app with HTML5-style URLs (i.e. with no # fragment in the URL). Thus in the routing controller module of my Angular app I’ve got something like the following:

angular.module('app').config(['$routeProvider','$locationProvider',function($routeProvider,$locationProvider) {
    $locationProvider.html5Mode(true)
...
}

$routeProvider
.when('/1/:param', /* do something */)
.when('/2/:param', /* do something else */)
.when('/3/:param', /* do something else again*/);

A number of working examples like AngularFun don’t use HTML5 mode. For a request like http://localhost:3005/#/1/foo, it’s clear that

  • the http://localhost:3005/ part is handled server-side / by Express. Express happily serves our Angular-enabled index.html
  • the /1/foo route is handled client-side by Angular’s router

Say our server.coffee looks, as standard, something like the below (we serve the static dist directory that contains our compiled, minified Angular sources:

express = require 'express'
routes = require './routes'
dir = "#{__dirname}/dist"            # sources live here
port = process.env.PORT ? process.argv.splice(2)[0] ? 3005
app = express()

app.configure -> 
    app.use express.logger 'dev'
    app.use express.bodyParser()
    app.use express.methodOverride()
    app.use express.errorHandler()
    app.use express.static dir       # serve the dist directory
    app.use app.router
    routes app, dir                  # extra custom routes

If we do use HTML5 mode, our URL http://localhost:3005/#/1/foo becomes http://localhost:3005/1/foo (no more hash #). This time, the entire URL is intercepted by Express, and it gets confused because we don’t define routes other than /.

What we would really like to say is that the latter part of the URL (/1/foo) should be ‘delegated’ to Angular for handling. How can we say this?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

It appears that it does all work. I didn’t do that work myself, however. I relied on this skeleton project:
https://github.com/thanh-nguyen/angular-express-seed-coffee

This allows you a certain degree of control over which paths are handled by the client and which by the server.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply