Apostolos
Apostolos

Reputation: 8101

How to remove the hash # from the angularjs ng-route

I am trying to use the locationProvider to remove the hashtag from the url routes in angular js but it gives me error.

app.js

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

eclassApp.config(['$routeProvider','$locationProvider',
    function ($routeProvider, $locationProvider){
        $routeProvider.
            when('/',{
                templateUrl: '/html/student-list.html',
                controller: 'StudentsListCtrl',
            }).
            when('/students/:studentId',{
                templateUrl: '/html/student-details.html',
                controller: 'StudentDetailsCtrl',

            }).otherwise({
                redirectTo: '/students'
            });
            $locationProvider.htmlMode(true);
    }]
);

the error:

 Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.3.13/$injector/modulerr?p0=eclassApp&p1=TypeE…oogleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.13%2Fangular.min.js%3A17%3A1)

Am I missing something?

EDIT: calling the html5Mode function with options object like this

$locationProvider.html5Mode({
    enabled:true
})

i get the following error (changed to angular full to get a better explanation of the error istead of the minified version)

Error: [$location:nobase] $location in HTML5 mode requires a <base> tag to be present!

http://errors.angularjs.org/1.3.13/$location/nobase

Upvotes: 15

Views: 33433

Answers (7)

alpesh
alpesh

Reputation: 19

  • Step1: Inject $locationProvider in config() function of angular root module and set html5Mode() to true, syntax is change on angular 1.3 version.

    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
    });
    
  • Step2: add below settings on web.config


<system.webServer>
  <rewrite>
    <rules>
      <clear />
      <rule name="AngularJS" enabled=true stopProcessing="true">
        <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern"^/(api)" negate="true" />
          </conditions>
        <action type="Rewrite" url="/index.html" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

Upvotes: 1

Raj Malakpet
Raj Malakpet

Reputation: 31

Tested on Angular 1.6.1 version:

It requires 3 steps to remove the hashtag (#) from URL.

Step 1: enable html5mode on locationProvider through Config. sample code:

app.config(function($locationProvider, $routeProvider){
            $locationProvider.html5Mode(true);
            $routeProvider.when('/', {templateUrl: 'partials/home.html'}).when('/info', {templateUrl: 'partials/info.html'});
        });

Step 2: provide a base href attribute in the head section of index.html. This should be placed on top of all script and CSS tags. the href attributes defines the relative path of your project. sample code: base href="/demo/". My demo application sits on root directory of Apache web server. If your application is a sub-directory, use: base href="/demo/sub-directory/" or base href="http://localhost/demo/sub-directory/"

Step 3: If you're running this AngularJS application on Apache server (Wamp, Mamp etc): from other StackOverflow posts, you should enable url-rewrite module. As of Apache version 2.2+, this can be achieved by using command: FallbackResource. Sample code: create an .htaccess file on root directory of Apache server. Add the below command and restart the server. Provide the relative path index.html which handles the 404 error caused due angular-route functionality. This should solve refresh/accessing deep-url's and all 404 errors.

FallbackResource /demo/sub-directory/index.html

Upvotes: 0

Luis Teijon
Luis Teijon

Reputation: 4899

Try this line:

$locationProvider.hashPrefix('!').html5Mode(true);

before this line:

$routeProvider.

Upvotes: 0

LOTUSMS
LOTUSMS

Reputation: 10240

I know this is a year old but I still, to this day, haven't found one concise and full solution to this. It's all bits and pieces from several answers all over the net, so I am going to explain it here in detail and hopefully it could be the one place where other visitors can get one full answer. *I would append to the answer but this is too long to do that. So, let's get started.

First you need to download either ngRoute or angular-ui-router. I choose the latter because it already contains all that it's in ngRoute and it still has more features. So why not?

  1. Go to your CMD and type this

    npm install --save angular-ui-router
    
  2. Now go to your app.js file and write your routes like this

    var app = angular.module('ngCribs', ['ui.bootstrap', 'ui.router']);
    
    app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
        // Application routes
        $stateProvider
            .state('index', {
                url: '/',
                templateUrl: 'views/partials/home.html'
            })
            .state('listings', {
                url: '/listings',
                templateUrl: 'views/partials/listings-list.html'
            });
    
        // For unmatched routes
        $urlRouterProvider.otherwise('/');
    
        $locationProvider.html5Mode(true);
    
    }]);
    
  3. For your next step, you need to go to your <head> and add your base directory

    <base href="/"> </base>
    
  4. By now, you shouldn't have the hashtag anymore BUT, if you go to any page other than / and reload it, you get an error and the page doesn't load. You need to tell your server how to treat your path and base directory. So to cure this dilemma, you need a server and I prefer Express, but you can use others out there. I recommend Express because at some point you will need to get involved with MEAN stacks and guess what? Other than Mongo, you are already using Angular and Node, so why not add Express to the mix?! Go to your CMD again and do this:

    $ npm install express --save
    
  5. Now that you have a server installed, you must create a server.js file and put it in the base of your directory and put the following in it. *ensure your folder paths match your directory so that they're found.

    var express = require('express');
    var server = express();
    
    server.use(express.static(__dirname + '/'));
    server.set('views', __dirname + 'views');
    server.set('js', __dirname + 'js');
    server.set('css', __dirname + 'css');
    
    server.get('/', function(req, res){
        res.render('index.ejs');
    });
    
    server.all('/*', function(req, res, next) {
        // Just send the index.html for other files to support HTML5Mode
        res.sendFile('index.html', { root: __dirname });
    });
    
    //the port you want to use
    var port = 3006;
    server.listen(port, function(){
        console.log('server listening on port' + port)
    });
    
  6. Not done yet. As soon as you try to run the server on port 3006 you will get an error. Back to CMD and type this:

    npm install ejs --save
    
  7. You are done, now you just need to run your server and leave it open. So from this point forward, anything you need to do in the CMD, you will need a second CMD window. (I normally have 4 running at the time. 1-server, 2-Gulp for BrowserSync, 3-MongoDB, 4-To download any dependencies I may need along the way). So go to your CMD and do this to run your server and minimize it out of the way

    node server.js
    
  8. Now, you are free to go to localhost:3006 and navigate as if you were in a live server that is already config for you.

Upvotes: 1

Giridhar Kumar
Giridhar Kumar

Reputation: 629

Steps to get rid of # from URL:

  1. Inject $locationProvider in config() function of angular root module and set html5Mode() to true

    angular.module( 'app', [ ] ).config(function( $locationProvider) {
       $locationProvider.html5Mode(true);
    });
    
  2. Include base tag in head section of first loading page of application..

Upvotes: 4

V31
V31

Reputation: 7666

There is an extra comma in dependency array that you have. You can remove the comma as well as include base tag in your head section of the html that you have and you are good with removal of hashtags

<base href="/">

Your dependency array:

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

Upvotes: 1

Rabi
Rabi

Reputation: 2220

you can use the $locationProvider like this -

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});

Alternatively, you can use the base tag in your index.html (I suppose this is your landing page)

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

Removing base tag may cause some side effects in old IE browser like IE9

Upvotes: 45

Related Questions