Upgrade Rails 6.1 Application to Hotwire

Robert Guiscard
3 min readDec 29, 2020

--

The new magic “Hotwire” is released. Here are some notes on how to use it in an existing Rails application. If you look at the hotwired-rails, you wil notice that it basically contains two gems: turbo-rails and stimulus-rails. And by reading these two gems, you will notice that turbo-rails is a upgraded version of turbolinks, and stimulus-rails is actually stimulus npm package. If you use webpacker for javascript, you do not need to run turbo:install and stimulus:install. Therefore, we only need to do two things to get hotwire work in existing Rails application:

  1. upgrade stimulus.js from 1.1.1 to 2.0.0
  2. replace turbolinks with turbo

Upgrade stimulus.js to 2.0.0

This part is easy. Just run yarn add stimulus. Start your application and look at the javascript console in web browser. It will remind you to replace data-target with data-[controller name]-target. If you use data: {target: 'hello.content'} before, it needs to become data: {hello_target: 'content'}. Note the underscore vs hyphen.

Replace turbolinks with turbo

There are detailed instructions in installing turbo and removing turbolinks in turbo-rails . Just follow it. In short, replace turbolinks with turbo in Gemfile and install npm packages through yarn.

If you do not yet plan to use all the fancy functions of turbo, you only need to read Turbo Drive, which is very similar to turbolinks.

In short, data-turbolinks-track becomes data-turbo-track; data-turbolinks="false"becomes data-turbo="false".

That’s it. Test your Rails application and see if it breaks anything. If not, you can take advantages of what hotwire (turbo + stimulus) can offer, such as Turbo Frames and Streams.

Rails unobtrusive scripting adapter

If you suddenly realize that all links with data-method do not work, you are not alone. By default, Rails create links to destroy with this style. If you remove @rails/ujs during the installation of turbo-rails, data-method will not work. There are two solutions:

  1. Add @rails/ujs back with yarn. I do not know any side effect for now.
  2. Use button_toinstead of link_to.

Render in Controller

Traditional form validation use render in controller when validation failed. It will not work with Turbo for now.

Use case #1 — tabs

It is quite common to have tabs, but how to implement depends. One is to have Javascript show and hide content according to selected tab (client-side). The other is to make several web pages corresponding to each tab (server-side). Now, Turbo frame allows you to use server-side approach, but minimize the page loading. Just put tab content (and probably tabs) under turbo-frame tag. That is probably the easiest way to use Turbo frame.

Use case #2 — modal

Some css-based modal use class to show and hide a modal. It is less flexible. Now, you can actually use Turbo frame to share the same modal by injecting content into an application-level modal. Just define an empty Turbo frame in application layout and replace it when needed. You probably need some Javascript if there are some interactive elements in the modal. A trivial issue I found is that Turbo will cache pages, which sometimes include the modal. When the cache is used by Turbo as preview before the real content is fetched, the modal will briefly show up. To fix it, I add this at application-level javscript:

document.addEventListener("turbo:before-cache", function() {
// Remove modal so that it will be not cached by Turbo
let modal_element = document.getElementById("app-modal");
if (modal_element) {
modal_element.innerHTML = "";
}
})

--

--

No responses yet