How to Set Up Sass Live Reloading in Rails Using Style Injection

Zachary Berkompas
Red Shift
Published in
3 min readMar 29, 2016

Last Thursday, I found myself twiddling my thumbs waiting for the browser to reload for the umpteenth time and render my tiny CSS tweaks. I thought it would be nice to have live reloading styles in Rails, like Phoenix, React, Ember or many other new web frameworks.

Then, the thought of the agonizingly slow Rails asset pipeline quenched my enthusiasm.

After digging into it for a while, I discovered that there are a couple of gems which now make it possible to live reload styles in Rails in under a second! I’d like to share how to set up Sass style injection on a Rails project.

How it works

Here’s how style injection works. First you make a change to your .css or .scss file. Guard notices that the file has been changed and that it is a .css file. It sends a message via a web socket to the browser saying the file has changed. Then the livereload.js script (which is injected in the <head> tag of every page) makes an http request to Rails to get the new version of the stylesheet. Rails receives the request, recompiles the file and delivers it back to the browser. The livereload.js script then swaps out the old stylesheet for the new and the rendered page reflects the new styles. Pretty cool, right?

Setup

As a Rails developer, you’re probably familiar with the Guard gem, which you can configure to run Rspec, Sidekiq, etc. Recently, Guard-livereload (which is linked to Rack-livereload) was released and now makes it possible to implement live reloading in any Rails app in a few quick steps:

1. Add Guard, Guard-livereload, and Rack-livereload to your development gem group of your Gemfile. You’ll also need rb-fsevent if you don’t already have it included in your Gemfile.

group :development do
gem “guard”, “>= 2.2.2”, require: false
gem “guard-livereload”, require: false
gem “rack-livereload”
gem “rb-fsevent”, require: false
end

Don’t forget to run bundle install afterwards. I included the required: false on all our Guard-related gems since I only need them on the command line and not in the Rails app itself.

2. Add the Rack-livereload configuration to your app/config/development.rb

rails.application.configure do
# Automatically inject JavaScript needed for LiveReload
config.middleware.insert_after(ActionDispatch::Static, Rack::LiveReload)
end

3. Set up the Guardfile configuration by running Guard init live reload. If you run into errors at this point, you can just add the example live reload block to your Guardfile.

guard :livereload do
watch(%r{app/views/.+\.(erb|haml|slim)$})
watch(%r{app/helpers/.+\.rb})
watch(%r{public/.+\.(css|js|html)})
watch(%r{config/locales/.+\.yml})
# Rails Assets Pipeline
watch(%r{(app|vendor)(/assets/\w+/(.+\.(css|js|html|png|jpg))).*}) { |m| “/assets/#{m[3]}” }
watch(%r{(app|vendor)(/assets/\w+/(.+)\.(scss))}) { |m| “/assets/#{m[3]}.css” }
end

4. Run your Rails server (or restart if it’s already running). Then run Guard -P livereload to start live reload. The terminal should print out the following notification:

06:57:53 — INFO — LiveReload is waiting for a browser to connect.

(Quick note about the -P option when running Guard: Using the -P flag only runs the block in the Guard file by the name you pass in afterwards, in this case livereload, making it easy to avoid running rspec and any other time consuming tasks that can wait until later.)

Once your browser is connected, the console should print out:

07:01:45 — INFO — Browser connected.

5. Great job! Now your Rails app is set up with .css and .scss live-reloading, which will in time save you hours and hours of waiting for that pesky browser to reload.

Test it out and let us know at Infinite Red what you think!

--

--

Published in Red Shift

The official Infinite Red publication for React Native design & development. We’re a fully distributed team building world-class apps for over 20 years for clients all around the world.

Responses (7)