Hotwire::Livereload

Automatically reload Hotwire Turbo when app files are modified.

https://user-images.githubusercontent.com/839922/148676469-0acfa036-832e-4b40-aa05-1fdd945baa1f.mp4

Dependencies

Getting started

Add hotwire-livereload to your Gemfile:

bundle add hotwire-livereload --group development

Run installer:

rails livereload:install

Folders listened by default:

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

The gem detects if you use jsbundling-rails or cssbundling-rails and watches for changes in their output folder app/assets/builds automatically.

Configuration

Listen paths

You can watch for changes in additional folders by adding them to listen_paths:

# config/environments/development.rb

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

You can disable default listen paths and fully override them:

# config/environments/development.rb

Rails.application.configure do
  # ...
  config.hotwire_livereload.disable_default_listeners = true
  config.hotwire_livereload.listen_paths = [
    Rails.root.join("app/assets/stylesheets"),
    Rails.root.join("app/javascript")
  ]
end

Force reload

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

Reload method

Instead of a direct ActionCable websocket connection, you can reuse the existing TurboStream websocket connection and send updates using standard turbo-streams:

# config/environments/development.rb

Rails.application.configure do
  # ...
  config.hotwire_livereload.reload_method = :turbo_stream
end

In that case you need to place hotwire_livereload_tags helper in your layout after the <%= action_cable_meta_tag %>.

<head>
  ...
  <%= action_cable_meta_tag %>
+ <%= hotwire_livereload_tags if Rails.env.development? %>
  ...
</head>

Listen options

Listen gem, which is used for file system monitoring, accepts options like enabling a fallback mechanism called "polling" to detect file changes.

By default, Listen uses a more efficient mechanism called "native" which relies on the operating system's file system events to detect changes. However, in some cases, such as when working with network-mounted file systems or in certain virtualized environments, the native mechanism may not work reliably. In such cases, enabling force_polling ensures that file changes are still detected, albeit with a slightly higher resource usage.

You may use listen_options to pass these options like:

# config/environments/development.rb

Rails.application.configure do
  # ...
  config.hotwire_livereload.listen_options[:force_polling] = true
end

Disable livereload

To temporarily disable livereload use:

bin/rails livereload:disable

To re-enable:

bin/rails livereload:enable

No server restart is required. Disabling is managed by tmp/livereload-disabled.txt file.

Development

To get started:

  1. Run npm install
  2. Run npm run watch

License

Hotwire::Livereload is released under the MIT License.