angularjsrouteslocation-provider

Angular JS routing is showing the file name in the URL (in localhost)


I have a website (not a project just website) in visual studio 2010. Just angular and HTML code.

When I debug using IE I have routing working currently but it is showing the file name of my first page (of my single page app) in the URL like this: http://localhost:1349/DP/index.html#/home

Routing works like this but I dont want to see the filename "index.html" or the "#" sign. I have seen many solutions and tried many things. None of them worked properly (so I wont post all what didnt work here).

The links to my pages are:

<li><a href="#home">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#history">History</a></li> <li><a href="#coachs">Coachs</a></li> <li><a href="#activities">Activities</a></li> <li><a href="#calender">Calender</a></li> <li><a href="#gallery">Gallery</a></li> <li><a href="#fundraisers">Fundraisers</a></li> <li><a href="#links">Links</a></li> <li><a href="#styletesting">Test Styles</a></li>

the routing code is:

[(function () { 'use strict';

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


// configure our routes
app.config(['$routeProvider','$locationProvider',
  function ($routeProvider, $locationProvider) {

    $routeProvider


        // catch all go home
        .when('/', {
            templateUrl: 'home.html',
            controller: 'homeController'
        })

        // route for the home page
        .when('/home', {
            templateUrl: 'home.html',
            controller: 'homeController'
        })

        // route for the about page
        .when('/about', {
            templateUrl: 'about.html',
            controller: 'aboutController'
        })

        // route for the contact page
        .when('/contact', {
            templateUrl: 'navbar.html',
            controller: 'contactController'
        })


        // catch all go home
        .when('/styletesting', {
            templateUrl: 'styleTesting.html',
            controller: 'styletestController'
        })


        /*
        // happens when nothing specificed
        .otherwise({
            redirectTo: '/'
        })
        */

        /*
        // not working/finding sites
        // if you don't wish to set base URL then use this
        $locationProvider.html5Mode({
            enabled: true,
            requireBase: false
        });        
        */
    }]);]

As you can see I have the locationprovider commented out because it is not working. I tried the but that did not work either.

With all my playing around with various solutions I either get a 404, my page loads but not the section in the ng-view page (so header and footer shows up and that is the code in the index.html).

What do I need to do to get this to work without showing the page URL?

NOTE: I am developing on localhost (IIS included/embeded in Visual Studio 2010, not stand alone IIS), and I will want to deploy this to a web host server under a root domain name. So it will need to work for to both (so I cant hard code full url paths/etc).


Solution

  • It's called pretty URL in angular. You need to do three things.

    1) in app.js you got to inject $locationProvider service and enable html5Mode routing. The html5Mode routing only works for browsers that support HTML5.

    app.config(["$locationProvider",
        function($locationProvider) {
            $locationProvider.html5Mode(true);
        }
    ]);
    

    If you are curious, you can check the browser for the html5 history API. If it is not supported it will automatically fallback to using the hash URL approach. https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag

    if(window.history && window.history.pushState){
        $locationProvider.html5Mode(true);
      }
    

    2) you need to set the base tag in the head tag of your index file.

    <head>
        <meta charset="utf-8">
        <base href="/">
    </head>
    

    If you don't want to set the base href tag, you can also do this

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

    3) Configuring server settings

    Apache :

    RewriteEngine On  
      # If an existing asset or directory is requested go to it as it is
      RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
      RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
      RewriteRule ^ - [L]
    
      # If the requested resource doesn't exist, use index.html
      RewriteRule ^ /index.html
    

    IIS:

    <system.webServer>
        <rewrite>
          <rules>
            <rule name="AngularJS" 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_URI}" pattern="^/(api)" negate="true" />
              </conditions>
              <action type="Rewrite" url="/" />
            </rule>
          </rules>
        </rewrite>
      </system.webServer>