84

I am trying to implement html5's pushstate instead of the # navigation used by Angularjs. I have tried searching google for an answer and also tried the angular irc chat room with no luck yet.

This is my controllers.js:

function PhoneListCtrl($scope, $http) {
    $http.get('phones/phones.json').success(function(data) {
        $scope.phones = data;
    });
}

function PhoneDetailCtrl($scope, $routeParams) {
  $scope.phoneId = $routeParams.phoneId;
}

function greetCntr($scope, $window) {
    $scope.greet = function() {
    $("#modal").slideDown();
    }
}

app.js

angular.module('phoneapp', []).
    config(['$routeProvider', function($routeProvider){
        $routeProvider.
            when('/phones', {
                templateUrl: 'partials/phone-list.html',
                controller: PhoneListCtrl
            }).
            when('/phones/:phoneId', {
                templateUrl: 'partials/phone-detail.html',
                controller: PhoneDetailCtrl
            }).
            otherwise({
                redirectTo: '/phones'
            });
    }])
rnrneverdies
  • 15,243
  • 9
  • 65
  • 95
hilarl
  • 6,570
  • 13
  • 48
  • 57

1 Answers1

129

Inject $locationProvider into your config, and set $locationProvider.html5Mode(true).

http://docs.angularjs.org/api/ng.$locationProvider

Simple example:

JS:

myApp.config(function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider
    .when('/page1', { template: 'page1.html', controller: 'Page1Ctrl' })
    .when('/page2', { template: 'page2.html', controller: 'Page2Ctrl' })
});

HTML:

<a href="/page1">Page 1</a> | <a href="/page2">Page 2</a>
Andrew Joslin
  • 43,033
  • 21
  • 100
  • 75
  • Could I see a code sample for this when there's already config() for routeProvider? Not sure if I'm supposed to be creating a new config() for this or adding it to the first as an array of configs, and also not sure what the configFn should be (http://docs.angularjs.org/api/angular.module) – Mike Crittenden Jun 24 '12 at 12:09
  • I have done the same but when i click /phones/:phoneId the template url become phones/partials/phone-detail.html and firebug net tab shows html page not found – Ajay Beniwal Sep 24 '12 at 16:59
  • I am also getting page not found whenever I navigate to a given url in the browser (e.g. `/home` instead of `/`). Have you tried enabling html5 for your own site? – Andriy Drozdyuk Dec 25 '12 at 03:16
  • 37
    You have to configure your server to allow you to pull pages correctly. When you try to navigate to `mysite.com/hello`, it is trying to GET that page from your server. Instead, you want the browser to GET `mysite.com` and then use angular to find the browser's location is `/hello` and go there. So you need to configure your server to give back the `mysite.com` data no matter which subdomain is entered. – Andrew Joslin Dec 27 '12 at 15:30
  • @AndyJoslin If the server is serving a REST API, how do you suggest it's configured? – andyczerwonka Dec 30 '12 at 19:45
  • 18
    I'd say put your rest API at `/api` or something, and then make everything but /api/* give out the index.html. – Andrew Joslin Dec 31 '12 at 15:47
  • Bump for Andy Joslin's ridiculously thorough followup. – ehfeng Jan 06 '13 at 00:54
  • why use a bare html link instead of pushstate? then you wouldn't have to worry about setting up handling on the server. The only reason I could think of is to support IE < 10. – davidjnelson Feb 22 '13 at 23:37
  • Does this fall back on the hash if the browser does not support pushstate? – CatDadCode Jun 17 '13 at 21:34
  • This works if linking after initial index.html is loaded. But if a derived link ie then accessed directly it results in 404. How would one work around that? – Robert Christian Jul 15 '13 at 04:45
  • "When you try to navigate to mysite.com/hello, it is trying to GET that page from your server. Instead, you want the browser to GET mysite.com and then use angular to find the browser's location is /hello and go there" - @AndyJoslin, won't delivering pages using this method block noscript users and robots? In the case of Google I guess http://goo.gl/flPXse, but it's a hassle... – Ian Clark Mar 03 '14 at 12:42
  • @AndyJoslin I tried out your suggestion. However, in my case, after returning `mysite.com/hello` the index.html, the various scripts/css in index.html starts to get requested with base url `mysite.com/hello` as opposed to `mysite.com/`. The actual scripts/css are at `mysites.com/js/` and not `mysites.com/hello/js/`. Is there a way in Angular.js to circumnavigate this problem? – Luke Apr 12 '14 at 02:09
  • @AndyJoslin Should one try using `.htaccess` rewrites in order to always point to the desired location (of the server)? Ir is there a better way? – developer10 Jun 12 '14 at 11:09
  • Is there a way to do so with static pages and not on a server? – Mohamed El Mahallawy Jul 05 '14 at 23:20
  • @Luke Yes, link your resources like this: ` – yerforkferchips Aug 02 '14 at 20:47