Using Browser Sync with Rails and Local SSL

I’ve always been a fan of LiveReload since I first saw it years ago. However, the rack-livereload gem hasn’t been updated in a long while, and the livereload parent project seems to have died out too. rack-liveload doesn’t support reloading on local HTTPS connections, which was a requirement on a recent project—I needed a new tool.

BrowserSync came to the rescue.

In most cases, using BrowserSync’s proxy mode to reverse proxy a rails app running via a *.dev pow domain works well. For this particular project, there were a couple of specific issues:

  • Many pages on the project force HTTPS. A common pattern is to disable HTTPS in development: I prefer to keep the development and production delta as small as possible, and keep any HTTPS redirects enabled in production active in development as well.
  • The site used oauth for local user authentication. Each oauth redirect URL needs to be specified in each oauth provider’s admin. This is a pain to manage, and becomes more a pain when a reverse proxy with a unique domain is used sometimes.
  • The SSL certs served by tunnelss were not valid for the BrowserSync server causing browsers to throw invalid certificate errors.

After a bit of digging, I found a way to use my existing *.dev setup with BrowserSync. Here’s how:

Setup Apache + Pow + Tunnelss

Read through this blog post to setup your development environment to serve SSL.

Point Browser Sync to Tunnelss-generated SSL Certificates

BrowserSync has a bunch of configuration options. Some are inaccessible via the command line interface and need to be specified in a javascript file passed to the command line app.

Here’s how to configure BrowserSync to use the tunnelss-generated SSL certs to serve the secure web sockets it uses for syncing:


module.exports = {
  // "logLevel": "debug",
  "files": [
  "https": {
    "key": process.env['HOME'] +  "/.tunnelss/key.pem",
    "cert": process.env['HOME'] + "/.tunnelss/server.crt"

Throw this configuration file in bs-config.js in the root level of your project and start the BrowserSync server with:

browser-sync start --config bs-config.js

Connect Your Rails (or Sintra) App to BrowserSync

To connect your application to the BrowserSync server, throw this simple javascript tag in your layout:

<% if Rails.env.development? %>
<script type='text/javascript' id="__bs_script__">//<![CDATA[
  document.write("<script async src='https://HOST:3000/browser-sync/browser-sync-client.js'></script>".replace("HOST", location.hostname));
<% end %>

Note that the above snippet does not define a browser sync version in the javascript. This makes this code a bit more resilient to browser sync updates.

I prefer this simple JS snippet to a middleware (like rack-livereload) that inserts the JS snippet into your site automatically. Keeping this code in your layout makes it easy to upgrade the code in the future, and is more declarative to new developers working on the project.