/ Ruby

Livereload + Hanami

In this article I'll show how to use LiveReload and Hanami.

Installing LiveReload

Add that to your Gemfile:

gem 'guard'
gem 'guard-livereload', '~> 2.5', require: false
gem 'rack-livereload' # if you don't want to use browser extension

Then run bundle install.

Preparing Guard for watching our files

By default, guard-livereload is targeted for RoR. We should change Guardfile
to:

guard 'livereload' do
  extensions = {
    css: :css,
    scss: :css,
    sass: :css,
    js: :js,
    coffee: :js,
    html: :html,
    png: :png,
    gif: :gif,
    jpg: :jpg,
    jpeg: :jpeg,
    # less: :less, # uncomment if you want LESS stylesheets done in browser
  }

  extensions.each do |ext, type|
    watch(%r{
          (?:apps) # /apps/
          (?:/\w+/assets/\w+/(?<path>[^.]+) # /apps/<app_name>/assets/<folder>/<file>
           (?<ext>\.#{ext})) # matching extension (must be first encountered)
          (?:\.\w+|$) # other extensions
          }x) do |m|
      path = m[1]
      "/assets/#{path}.#{type}" # Hanami puts compiled assets in development env here
    end
  end
end

This config make Guard watch for ./apps/<app_name>/assets/<folder>/<file>.
Once something will be changed there, guard-livereload will sent a RELOAD
signal to our browser: RELOAD /assets/<file>.

Enabling LiveReload

Browser extension (preferred)

Install the corresponding extension for your browser:

You can find more ways to install it on the official website.

Rack gem

Add this code to /config.ru before run Hanami::Container.new:

require 'rack-livereload'
use Rack::LiveReload

This will enable rack-livereload globally.

Fixing Content Security Policy

If you run guard and hanami server and try to open your site, you'll see
Content Security Policy error in your console. The problem here is guard will
host it's own livereload.js at localhost:35729 and rack-livereload will be
trying to inject it. But hanami does not allow including scripts and
connecting to WebSockets from external resources.

We'll change CSP to allow loading inline scripts and scripts from localhost:35729.

Change security.content_security_policy %{...} in apps/<app>/application.rb to:

security.content_security_policy %{
  ...
  script-src 'self' http://localhost:35729/ 'unsafe-inline';
  connect-src 'self' ws://localhost:35729/;
  ...
}
end

We allowed inline scripts because rack-livereload injects some variables in
this way for livereload.js
(such as RACK_LIVERELOAD_PORT and WEB_SOCKET_SWF_LOCATION).

We allowed scripts from localhost:35729 and connections to localhost:35729.
livereload.js will be trying to connect to ws://localhost:35729. That's why
we allow to do it in CSP.

Testing LiveReload

Run guard and hanami server. Open localhost:2300 and change any resource
(a css file for example). Your changes should be applied immediately.

If you're using the extension for browser, don't forget to connect to the
livereload server by clicking on the toolbar button.

Have fun! :)