Angular1系のhtml5Modeでルーティングする

初めにアクセスされたページがトップページではない時のルーティングでAngularの設定で迷ったのでメモしておきます。

初めにアクセスされたページが http://localhost/ の場合は / がベースになることが分かるのですが、初めに http://localhost/item/1 にアクセスされるとベースがそこになってしまい item/1 にアクセスしたい場合は http://localhost/item/1/item/1 にしないといけなくなります。

色々試してみたのですが、結果としてAngularの設定はこんな感じになりました。

class AppController {
    constructor(private $router: AppScope) {
        $router.config([
            { path: '/item/:id', component: 'item' },
            { path: '/**', component: 'home' }
        ]);
    }
}

angular.module('app', ['ngNewRouter', 'app.home', 'app.item'])
    .config(['$locationProvider', ($locationProvider) => {
        $locationProvider.html5Mode({enabled: true, requireBase: true});
    })
    .controller('AppController', ['$router', AppController]);

*1

ポイントとしては html5ModeのrequireBase: trueの部分です。この設定をすることでルートのhtmlにベースパスを指定することができます。以下のように設定することで、http://localhost/item/1 にアクセスしても http://localhost/ をベースとして解釈して適切に処理してくれます。

<head>
    <base href="/">
    ...
</head>

これでサーバはどのURLでアクセスがきてもルートのhtmlを返すように設定しておけば、Angularがうまく処理してくれるはずです。

*1:ルーティングのモジュールであるngNewRouterにはotherwiseがないようで、{ path: '/**', component: 'home' } こう書くことで同じように動作させるみたいです。 https://github.com/angular/router/issues/110