Last night I decided it would be a good idea to join the 21st century and incorporate LiveReload into my frontend workflow. Since I’m already using grunt-contrib-watch to watch my LESS/SASS files, I figured this would be a breeze. grunt-contrib-watch supports LiveReload out of the box! All that was needed was an options block inside of my watch config:

watch: {
    options: {
        livereload: true,
    },
    ...

This option spins up a LiveReload server on my dev machine running on port 35729 by default. In order to leverage LiveReload, your client must include the livereload.js script served by this service. This can be done by either manually adding a script tag to your project, or using the Chrome LiveReload extension. I quickly installed the extension, eagerly pressed the LiveReload button and… got an error!

Could not connect to LiveReload server. Please make sure that a compatible LiveReload server is running. (We recommend guard-livereload, until LiveReload 2 comes to your platform.)

Strange. My dev server was running on a VM on 192.168.0.12, so to verify that the LiveReload server was running I went to http://192.168.0.12:35729/ in the brower. As expected, I received a JSON response from grunt-contrib-watch’s tinylr server:

{
    "tinylr": "Welcome",
    "version": "0.0.5"
}

Very strange. Livereload was running on my dev machine, but the Chrome extension was unable to connect to it. As a sanity check, I decided to forgo connecting with the browser extension and manually added the livereload.js script tag to my project:

<script src=”http://192.168.0.12:35729/livereload.js”></script>

After reloading the page, I noticed that it was able to successfully pull down the livereload.js file and LiveReload changes were taking effect.

While this approach worked, I wasn’t satisfied. I wanted to use the browser extension, not manually include the script in my project. I started digging into the plugin to find out what was going on.

The first thing I did was enable “Developer Mode” in the Chrome extensions window. That allowed me to install and enable the Chrome Apps & Extensions Developer Tool. I fired up the Extension Dev Tools, opened the LiveReload console and once again tried to connect to my dev server. The log messages made it clear what was going on:

Connecting to ws://127.0.0.1:35729/livereload...
Haven't received a handshake reply in time, disconnecting.
WebSocket connection to 'ws://127.0.0.1:35729/livereload' failed: WebSocket is closed before the connection is established.
Web socket error.
Web socket disconnected.

The LiveReload extension was attempting to connect to 127.0.0.1, not 192.168.0.1. A quick look through global.js shows that host is hardcoded to 127.0.0.1 in the initialize function.

After looking through the github issues for the LiveReload extension project, I found an unmerged pull request from 2013 by Greg Allen that fixed the issue. Bigwave in the comments had built a version of the extension with the fix and released on the app store as RemoteLiveReload. After installing this new extension, my LiveReload setup started working without a hitch. Thanks Greg and Bigwave!