Search code examples
javascripthtmlangularjsnode.jsngroute

Getting rid of #! in angularjs ngRoute


I'm working with Angularjs ngRoute for SPA with Node.js as my backend, I have 3 pages in my website say:

  • localhost:8000/#!/
  • localhost:8000/#!/red
  • localhost:8000/#!/green

By googling I found the way to get rid off /**#!**/ and it worked fine only when a user has no intention to press F5 to reload a page. If reloaded, structure of my page becoming worse. What I mean, If a user pressed F5 when he/she is in red.html page, then red.html alone displayed instead of injecting the red.html content in ng-View Thats the nature of nodejs get request. Is there any ways to get rid off from this problem?

index.html

<body ng-app="myApp">
  <p><a href="/">Main</a></p>
  <a href="/red">Red</a>
  <a href="/green">Green</a>

  <ng-view></ng-view>

  <script>
    var app = angular.module("myApp", ["ngRoute"]);
    app.config(function($routeProvider, $locationProvider) {
      $routeProvider
        .when("/", {
          templateUrl: "/main"
        })
        .when("/red", {
          templateUrl: "/red"
        })
        .when("/green", {
          templateUrl: "/green"
        })

      $locationProvider.html5Mode(true);
    });

  </script>
</body>

Solution

  • You are using node.js with express, right? In that way just link all your application view routes to your index.html and put your partial views in an other subdirectory to avoid route conflicts:

    //resources 
    app.use("/js", express.static(__dirname + "/js"));
    app.use("/img", express.static(__dirname + "/img"));
    app.use("/css", express.static(__dirname + "/css"));
    
    //different path for your partials to avoid route conflicts
    app.use("/partials", express.static(__dirname + "/partials"));
    
    //view routes
    app.get('/*', function(req, res){
        res.sendFile(__dirname + '/index.html');
    });
    

    In that way all your routes:

    • localhost:8000/
    • localhost:8000/red
    • localhost:8000/green

    will point at your index.html. So your $routeProvider will be able to inject the view in the right way, while your index.html will be loaded every time.

    Finally your route configuration should look like this:

    var app = angular.module("myApp", ["ngRoute"]);
    app.config(function($routeProvider, $locationProvider) {
      $routeProvider
        .when("/", {
          templateUrl: "/partials/main.html"
        })
        .when("/red", {
          templateUrl: "/partials/red.html"
        })
        .when("/green", {
          templateUrl: "/partials/green.html"
        })
    
      $locationProvider.html5Mode(true);
    });