Search code examples
gruntjsserver-sideng-view

Is there a Grunt plugin to compile angular ng-views for server side rendering?


I have a simple angular app managed by Grunt.js. I use the angular router for different pages:

index.html

...
<body ng-app="app">
   ...
   <div ng-view></div>
   ...
</div>
...

_users.html

<h1>Users</h1>
...

app.js

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

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/', {
            templateUrl: 'views/_home.html',
            controller: 'HomeCtrl'
        }).
        when('/users', {
            templateUrl: 'views/_users.html',
            controller: 'UsersCtrl'
        }).
        otherwise({ redirectTo: '/' });
}]);

// ... controllers

The routing works fine for client side rendering, e.g requests of the form site.com, site.com/#/users, etc. If I apply $locationProvider.html5Mode({ enabled: true }), a direct call for site.com/users will fail, because there are no users.html or users/index.html files. Is there a smart grunt plugin which knows to render the views inside the layout when building a distribution directory? That is, generate a directory structure like for every nested view:

dist
├── index.html
└── users
│   └── index.html
├── css
│   └── app.css
└── js
    └── app.js

Thanks.


Solution

  • So, to sum up our discussion in comments :

    1. To get nice urls : you should configure $locationProvider and set html5Mode to true

    2. Then, your server should look at the requested folders (i.e. looking into the folder my-folder for the URL site.com/my-folder/) so it won't work

    3. So you have to make a basic rewrite rule in your htaccess (assuming you're working on Apache server), something like that (assuming index.html is the entry point of your app :

    >

    RewriteEngine on
    RewriteCond %{REQUEST_URI} !^/index.html$
    RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css|js)$
    RewriteRule .* /index.html [L,R=302]
    

    From Angular doc : https://docs.angularjs.org/guide/$location#server-side

    Unless if you really want to have static files to serve to the client (for any reason), this is the solution.