Kirill Platonov
Kirill Platonov
All Posts Jan 9, 2022

Live reloading for Hotwire Rails apps

Personally, I never used live reloading in Rails apps apart from the one that comes with webpacker gem. But things changed when I started working on embedded Shopify apps. They’re loaded as an iframe inside the Shopify admin panel. And reloading parent page + iframe together is pretty slow. This made editing views, CSS, or JS pretty painful 😞. To see the results of my changes I have to wait for 4-5s for browser to reload the page. At this point, I started to think that there should be a better way and started exploring live reloading.

Usually, live reloading is done by fully reloading browser page via location.reload();. But this wasn’t sufficient for my use case. I wanted to only update page content without doing a full page reload. Luckily my apps were built with Hotwire Turbo. And Turbo already knows how to reload only the content inside body without reloading the whole page. All I needed to do is to teach Turbo how to reload the current page when app’s view, CSS, or JS files are changed.

This is how Hotwire::Livereload gem was born. I created a simple Rails engine that uses listen gem to track changes in app files and sends reload requests to Turbo via ActionCable when files are changed. As a result, we get very fast live reloading without a full browser refresh. Exactly what I was needed.

Getting started

To start using Hotwire::Livereload add it to Gemfile:

bundle add hotwire-livereload --group development

And run installer:

rails livereload:install

That’s basically it! By default the gem will listen for changes in the following folders:

  • app/views
  • app/helpers
  • app/javascript
  • app/assets/stylesheets
  • app/assets/javascripts
  • app/assets/images
  • app/components
  • config/locales

This covers the most common use cases. But you can tweak it with configuration if needed.

Configuration

To listen for custom folder add:

# config/environments/development.rb

Rails.application.configure do
  # ...
  config.hotwire_livereload.listen_paths << Rails.root.join("app/custom_folder")
end

If you don’t have data-turbo-track="reload" attribute on your JS and CSS bundles you might need to setup force reloading. This will trigger full browser reloading for JS and CSS files only:

# config/environments/development.rb

Rails.application.configure do
  # ...
  config.hotwire_livereload.force_reload_paths << Rails.root.join("app/assets/stylesheets")
  config.hotwire_livereload.force_reload_paths << Rails.root.join("app/javascript")
end

Disable livereload

In case if you want to disable live reloading temporarily you can do it using the following rake task:

bin/rails livereload:disable

This will create tmp/livereload-disabled.txt file and will stop live reloading immediately. No server restart is required. To enable it again run:

bin/rails livereload:enable

Wrapping up

Live reloading is a very handy tool for modern web app development. I found it especially useful for Rails apps with TailwindCSS and for embedded Shopify apps. And Hotwire::Livereload gem makes it very easy to setup live reloading for Hotwire Rails apps. I will use it in all of my Rails apps moving forward. And I hope you’ll find it useful too.

If want to hear more from me follow me on Twitter. I tweet about my journey of building and growing Shopify apps using Ruby on Rails, Hotwire, and Polaris ViewComponents.

Subscribe to get new blog posts via email

Or grab the RSS feed