Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

html5 mode with grunt serve not working

In grunt file, livereload block looks like this:

livereload: {
  options: {
    open: true,
    middleware: function(connect, options, middleware) {
      var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
      return [
        [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat(
          optBase.map(function(path) {
            return connect.static(path);
          })),
        connect.static('.tmp'),
        connect().use(
          '/bower_components',
          connect.static('./bower_components')
        ),
        connect().use(
          '/app/styles',
          connect.static('./app/styles')
        ),
        connect.static(appConfig.app)
      ];
    }
  }
},

Adding:

 [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat(
                    optBase.map(function(path){ return connect.static(path); })),

did use to work for me to enable html5 mode, otherwise, my routes do not load without #! when I try to reload via the browser.

I do have base href='/' added and html5Mode(true) in config. Is there anything else I can try? Why would it really stop working?

Note: Turns out that my URL has a dot in it and that is not being handled by connect-mod rewrite rule so well. Any idea how to change that and enable it to handle dot in URL?

like image 291
S Khurana Avatar asked Sep 24 '17 07:09

S Khurana


2 Answers

Try adding this in root app module in the config block. Make sure to include/inject $locationProvider.

$locationProvider
  .html5Mode({
    enabled: true,
    requireBase: false
  })
  .hashPrefix('!');
like image 75
alphapilgrim Avatar answered Oct 22 '22 21:10

alphapilgrim


I believe the dot problem is a side effect of the general problem. Have the same setup, more or less. I simply reset the html5Mode in .config() like this :

if (window.location.host == 'localhost:9000') {
   $locationProvider.html5Mode(false);
   $locationProvider.hashPrefix('');
} else {
   $locationProvider.html5Mode(true);
}

The app will still prefix all urls with #/ in development mode, making urls, linking and livereload a pain. Solved this by a small directive that changes regular /urls to /#/urls :

var isLocalHost = (location.hostname === "localhost" || location.hostname === "127.0.0.1");
angular.module('myApp').directive('debugLink', function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      $timeout(function() {         
        var href = element.attr('href');
        if (href && isLocalHost && href.charAt(0) == '/') {
          element.attr('href', '#'+href);
        }
      }, 100);
    }
  }
});

Now linking can be done by <a href="/url" debug-link>link</a>

Finally I use the .htaccess redirect from https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode on the production server

RewriteEngine on

# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]

I use this approach in several angularjs+grunt projects. It prevent the livereload from breaking, i.e when I hit Ctrl-S the page is refreshed, and I can use the correct urls anywhere. I guess no one is interested in having prefixes or hashes in production mode.

like image 40
davidkonrad Avatar answered Oct 22 '22 21:10

davidkonrad