Using Browser Sync with Rails and Local SSL
Categories: Web Development
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:
// https://www.browsersync.io/docs/options
module.exports = {
// "logLevel": "debug",
"files": [
'**/*.css*',
'**/*.html*',
'**/*_controller.rb',
'**/*.md'
],
"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));
//]]></script>
<% 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.