50

I want to active html5Mode in angularJS, but I don't know why it's not working. Is there anything wrong with my code?

angular
    .module('myApp',[])
    .config(function($locationProvider, $routeProvider) {
        $locationProvider.html5Mode(true);
        $routeProvider.when('/', {
           templateUrl: 'partials/home.html', 
           controller: HomeCtrl
        });

        $routeProvider.when('/tags/:tagId', {
            templateUrl: 'partials/result.html', 
            controller: TagResultCtrl
        });
        //$routeProvider.otherwise({redirectTo: '/home', controller: HomeCtrl});
     });

in html

  <a href="tags/{{tag.id}}"><img data-ng-src="{{tag.imageUrl}}"></a>
activedecay
  • 10,129
  • 5
  • 47
  • 71
vzhen
  • 11,137
  • 13
  • 56
  • 87

6 Answers6

63

The only issue I see are relative links and templates not being properly loaded because of this.

from the docs regarding HTML5 mode

Relative links

Be sure to check all relative links, images, scripts etc. You must either specify the url base in the head of your main html file (<base href="/my-base">) or you must use absolute urls (starting with /) everywhere because relative urls will be resolved to absolute urls using the initial absolute url of the document, which is often different from the root of the application.

In your case you can add a forward slash / in href attributes ($location.path does this automatically) and also to templateUrl when configuring routes. This avoids routes like example.com/tags/another and makes sure templates load properly.

Here's an example that works:

<div>
    <a href="/">Home</a> | 
    <a href="/another">another</a> | 
    <a href="/tags/1">tags/1</a>
</div>
<div ng-view></div>

And

app.config(function($locationProvider, $routeProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider
    .when('/', {
      templateUrl: '/partials/template1.html', 
      controller: 'ctrl1'
    })
    .when('/tags/:tagId', {
      templateUrl: '/partials/template2.html', 
      controller:  'ctrl2'
    })
    .when('/another', {
      templateUrl: '/partials/template1.html', 
      controller:  'ctrl1'
    })
    .otherwise({ redirectTo: '/' });
});

If using Chrome you will need to run this from a server.

empiric
  • 7,825
  • 7
  • 37
  • 48
jaime
  • 41,961
  • 10
  • 82
  • 52
  • 10
    It isn't really explained here, but when using HTML5 mode, your browser will actually request the full URL (including the state) from the server any time the user directly enters the URL, navigates to the URL from another server, or hits refresh. Since your AngularJS app is likely a single-page application, this means the server will return a 404 Not Found error because it only knows about index.html. To fix this, you must set up your server to return your index.html for all 404 errors, then handle unexpected states in your route provider (i.e .otherwise({ redirectTo: '/404-not-found' }) ) – Ryan Kimber Jun 26 '14 at 20:40
  • hot to fix when reaload pagge gives 404 :s – Alberto Acuña Apr 22 '17 at 11:29
5

Following is how one can configure $locationProvider using requireBase=false flag to avoid setting base href <head><base href="/"></head>:

var app = angular.module("hwapp", ['ngRoute']);

app.config(function($locationProvider){
    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
    }) 
});
Sruthi Poddutur
  • 1,371
  • 13
  • 7
  • This works great to solve my problem. However, I am using search parameters in my url, and when I add this code I no longer am able to refresh the page. Do you know why this could be? – user613 May 17 '22 at 19:24
4

AngularJS provides a simple and concise way to associate routes with controllers and templates using a $routeProvider object. While recently updating an application to the latest release (1.2 RC1 at the current time) I realized that $routeProvider isn’t available in the standard angular.js script any longer.

After reading through the change log I realized that routing is now a separate module (a great move I think) as well as animation and a few others. As a result, standard module definitions and config code like the following won’t work any longer if you’re moving to the 1.2 (or future) release:

var app = angular.module('customersApp', []);

app.config(function ($routeProvider) {

    $routeProvider.when('/', {
        controller: 'customersController',
        templateUrl: '/app/views/customers.html'
    });

});

How do you fix it?

Simply add angular-route.js in addition to angular.js to your page (grab a version of angular-route.js here – keep in mind it’s currently a release candidate version which will be updated) and change the module definition to look like the following:

var app = angular.module('customersApp', ['ngRoute']);

If you’re using animations you’ll need angular-animation.js and also need to reference the appropriate module:

 var app = angular.module('customersApp', ['ngRoute', 'ngAnimate']);

Your Code can be as follows:

    var app = angular.module('app', ['ngRoute']);   

    app.config(function($routeProvider) {

    $routeProvider
        .when('/controllerone', {
                controller: 'friendDetails',
                templateUrl: 'controller3.html'

            }, {
                controller: 'friendsName',
                templateUrl: 'controller3.html'

            }

    )
        .when('/controllerTwo', {
            controller: 'simpleControoller',
            templateUrl: 'views.html'
        })
        .when('/controllerThree', {
            controller: 'simpleControoller',
            templateUrl: 'view2.html'
        })
        .otherwise({
            redirectTo: '/'
        });

});
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Suu
  • 66
  • 2
3

Try this

If you are deploying your app into the root context (e.g. https://myapp.com/), set the base URL to /:

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

Angular Documentation

Hassan Jamal
  • 694
  • 9
  • 11
  • 1
    This is indeed something that has been fixed in the current releases of angular; You may want to make sure it's understood the version of angular this answer applies to, since this question was originally posted and answered in 2012, and this answer wouldn't have been appropriate for the angular version available then. – Claies Aug 15 '15 at 21:56
0

you could try:

<a href="#/controllerone">Controller One</a>||
<a href="#/controllerTwo">Controller Two</a>||
<a href="#/controllerThree">Controller Three</a>

<div>
    <div ng-view=""></div>
</div>
Our Man in Bananas
  • 5,809
  • 21
  • 91
  • 148
Suu
  • 66
  • 2
0

@Simple-Solution

I use a simple Python HTTP server. When in the directory of the Angular app in question (using a MBP with Mavericks 10.9 and Python 2.x) I simply run

python -m SimpleHTTPServer 8080

And that sets up the simple server on port 8080 letting you visit localhost:8080 on your browser to view the app in development.

Hope that helped!

fnc314
  • 1
  • 1