Hotwire: Turbo and Stimulus in a nutshell
Hotwire stands for “HTML over the wire” and the goal is to build client-side interactivity without writing (much) JavaScript. For that, Turbo manages HTML requests to the server and directs responses, and Stimulus - a minimal JavaScript library - manages the interactions that Turbo can’t handle.
Turbo
The Turbo Drives (old Turbolinks) captures all link clicks and form submissions, and extracts the body from the response in order to replace it in the existing page. Behind the scenes, it also does some work to keep the browser back button working and manages caches.
A Turbo Frame is a custom HTML tag (<turbo-frame id="ID">)
that allows a small part of the page to behave the way Turbo Drives treats the entire page.
In summary, with Turbo Frames:
- A response can only change one DOM element.
- A response will update the inner HTML of the element.
- The affected element must be a
turbo-frame
with the same DOM id. - Turbo Frames are evaluated on any navigation inside a
turbo-frame
element.
A Turbo Stream is another custom HTML tag (<turbo-stream action="ACTION" target="TARGET">
) that allows multiple parts of the page to be updated from a single request. They are also designed to work with WebSockets via ActionCable.
In summary, with Turbo Streams:
- A response can change multiple DOM elements.
- A response can append, prepend, remove, replace, update or insert content before or after the affected elements.
- Affected elements can be any type of HTML with a matching DOM id (
turbo-stream
target). - Turbo Streams are evaluated on form responses or Action Cable broadcast.
Stimulus
Stimulus is particularly good for interactions that are relatively small and are expansions of existing browser capabilities. A few concepts that describe how HTML markup relates to the JavaScript code:
- Controllers are where the Stimulus JavaScript code goes. They are invoked by adding the
data-controller="controller-name"
(dash-case) attribute to the DOM element and they contain methods that are called in response to events that happen. - Actions connect a DOM event to the controller code that is executed when the event happens. The
data-action="event->controller-name#actionName"
is the attribute name that signs to Stimulus that an action is being defined. - Targets are DOM elements used by controllers to determine the state of the page or to be changed according to the state of the page. They are identified by the attribute named
data-<controller-name>-target="targetName"
. Stimulus defines three properties on the controller for target elements:<targetName>Target
,<targetName>Targets
andhas<targetName>Target
. - Data maps and values are the state that is stored in the DOM. The attribute name for values is
data-<controller-name>-<attribute-name>-value="value"
. The allowed types for values areArray
,Boolean
,Number
,Object
orString
. For non-array values, Stimulus creates<attributeName>Value
andhas<attributeName>Value
properties. Same for arrays but in plural:<attributeName>Values
andhas<attributeName>Values
. - Classes: CSS classes that represent the state. The name of the data attribute has the form
data-<controller-name>-<description>-class="class"
. As expected, Stimulus creates a few properties for classes:<description>Class
andhas<description>Class
.
References:
- Modern Front-End Development for Rails by Noel Rappin
- Hotwire for Rails Developers course by The Pragmatic Studio