00:00:15.280
So nice to be here with you. Thank you all for coming. My name is Yaroslav, and I'm from Ukraine. You might know me from my blog or from my SuperAils YouTube channel, where I post a lot of content about Ruby on Rails, especially about Hotwire.
00:00:27.800
I originate from northern Ukraine, and I used to live just 80 kilometers away from Chernobyl. That area is now liberated, which is great. However, my family's home was burned in one of the early days of the war.
00:00:40.239
My godfather went to defend Ukraine. Despite the war, we're dealing with it. Just today, the city of Kharkiv was randomly bombed by the Russians, affecting many people, including those from the Ruby on Rails community in Ukraine, some of whom are actively fighting.
00:01:00.000
On a positive note, I recently became a father just two and a half months ago in France. Today, we're going to talk about Hotwire.
00:01:13.159
We had a nice talk by Jorge about Turbo, discussing its future. Then there was Marco, who spoke about the many tools in the Hotwire ecosystem. He brings all the tools to the table, while I'm doing the cooking—hence the title, the Hotwire Cookbook.
00:01:27.800
Last week, I was in Romania and received a beautiful cookbook. I prepared the Hotwire Cookbook presentation during my time there.
00:01:35.000
I've created a lot of videos covering different aspects of Hotwire, such as Turbo, Stimulus, and Turbo Streams. You can check out the 'Just Enough Hotwire for Rails Developers' series on my channel, which has become quite popular recently.
00:01:55.600
In this presentation, I'm going to show you a few common recipes and the simplest things you can build with different parts of Hotwire. We will cover Turbo Drive, Turbo Frames, Turbo Streams, and Stimulus.
00:02:10.959
While speaking with many people in the lobby, I found that a lot of them identified as backend developers—specifically as Rails backend developers. Many have heard of Hotwire, and some have tried it.
00:02:32.799
Could I see a show of hands from those who have not yet tried Hotwire? Hmm, okay, I’ll primarily target you with these very simple recipes to help you understand the basics.
00:02:44.159
We'll start with Turbo Drive. Although it’s been said that Turbolinks is dead, I see Turbo Drive as a combination of Turbolinks and Rails UJS.
00:03:01.159
For years, I simply kept the Turbolinks gem in my Gemfile, sometimes disabling it, along with Rails UJS. I never really understood why, but I maintained both until now, as we only need the Turbo Rails gem to handle everything.
00:03:44.160
So, what does Turbo Drive do? It has some explicit features you can utilize. For example, previously with Rails 6 and earlier versions, you were able to use 'link_to' with non-GET requests, but Rails UJS was deprecated and is no longer part of the default stack. However, now you can use 'link_to' with the data-turbo-method attribute set to delete, and Turbo will handle it.
00:04:58.840
It's suggested that if you’re not making a GET request, you should use a button instead. Additionally, in earlier versions using Rails UJS, you could prompt for confirmation using data-confirm. Now, with Turbo, you use data-turbo-confirm. Migrating from previous versions of Rails to Rails 7 is straightforward.
00:05:55.960
Furthermore, you might notice a feature called 'disable on submit.' You click submit and can’t click it again, boosting user experience. Turbo provides methods to handle this seamlessly. One of my favorite features allows persistent elements across different pages. This means that in a demo, when I click a video or audio, those elements maintain state across transitions.
00:06:36.800
Each element that should remain persistent needs to have a unique ID and include data-turbo-permanent set to true. This behaves like the 37signals podcast, where if I click play and navigate, the player continues playing because it’s using data-turbo-permanent as well.
00:07:30.200
Another usage example of data-turbo-permanent can be seen on my SuperAils website, which allows for searching. If I search and navigate to another page, the search results persist, saved only in the HTML.
00:08:18.320
Sometimes, you’ll need to disable Turbo, particularly when dealing with devices that aren’t compatible. For example, you might add data-turbo-frame to actions that could perform a redirect.
00:08:59.500
Next, let’s discuss Turbo Frames. Turbo Frames have two main features: lazy loading and self-contained page elements. Lazy loading allows for a collection of records to load as you scroll through an employee page, improving page load speed.
00:09:35.200
I’ll show you through a hustle-free interface how lazy loading works. When an element becomes visible on the page, it automatically makes a request to load its content. Using 'loading lazy' ensures items load only as needed. For example, if you click my avatar on Basecamp, a request is made only when needed, so it doesn't waste resources.
00:10:34.760
Another way lazy loading can be implemented is through the HTML details tag, which allows you to load elements upon unhiding them. With Twitter and GitHub, hovering over profiles initiates new requests without preloading all profiles, thus managing memory effectively.
00:11:17.680
Turbo Frames also support self-contained page elements, critical for tasks like searching and filtering through tables. As I type in the search field, each entry immediately updates the displayed results, further ensuring the URL is automatically refreshed with new search queries.
00:12:15.840
To accomplish this, I'm using Turbo Frame around my search elements. When I submit the form, the response updates only the designated Turbo Frame elements rather than refreshing the entire page.
00:12:46.960
After discussing search, let’s move to sorting functionalities. I implemented sortable links. Similar to search, sorting requires an update to the URL. To achieve that, I’ve added the 'data-turbo-action' attribute to the relevant Turbo Frame.
00:13:50.200
Now we can also discuss inline editing. Imagine working on a list of employees; if I want to edit a specific attribute, I click on it, which triggers a request to the edit page and updates that field directly.
00:14:48.760
Each attribute is wrapped in a separate Turbo Frame, ensuring that only that specific attribute requests and updates while leaving the rest unaltered. You can explore my GitHub for extensive examples and further material on Hotwire.
00:15:29.560
Another interesting feature is chained selects. Historically, I’ve seen companies using React just for this simple UX pattern, but with Turbo Frames, you can easily implement this without the overhead of a full framework.
00:16:17.759
For example, after selecting a country, I can then select a state, followed later by a city. All without unnecessary page reloads and with just a few components.
00:17:15.320
When it comes to modals, if I want to edit an employee's information, I click on the 'new employee' button. If any errors arise during input, they will render directly within the modal, keeping the user's flow uninterrupted.
00:18:05.319
To implement this, the link to the 'new employee' action has a data-turbo-frame attribute. Consequently, Turbo knows to display this action in the modal. Likewise, the modal is wrapped in a Turbo Frame to facilitate clear rendering.
00:18:49.280
Returning to Turbo Frames, they can feel quite complex initially. If you identify as a backend developer and want to dapple in Turbo, begin by inspecting Turbo requests through the browser's network tab.
00:19:41.960
This ensures that you employ different data attributes correctly for replacing elements. I recommend gaining a good understanding of how HTML forms work, specifically when differing submit buttons are involved.
00:20:20.079
Next, we’ll transition into Turbo Streams. For me, Turbo Streams resemble rebranded JS. Previously, with format JS response types, you’d replace an element on the page dynamically.
00:21:10.230
Now, with Turbo Streams, we use the format turbo_stream. You can perform operations such as updating, removing, or adding elements dynamically.
00:21:53.639
For example, I can easily add or update elements without a page refresh. When submitting records for employees, the list updates dynamically as you modify the details.
00:22:32.549
In practice, when an employee is deleted, a Turbo Stream action removes the relevant element from the list visually in real-time without needing a full page refresh.
00:23:29.440
To further enhance user experience, Turbo Streams can be combined with Turbo Frames for functionalities like infinite pagination. When scrolling down, more content can automatically be fetched and displayed.
00:24:40.080
Turbo Streams can also incorporate broadcasts using Action Cable to allow real-time updates between users. This is crucial for features like live chats where message updates should seamlessly reflect across different users without page refreshes.
00:25:24.960
While implementing live messages, Turbo Streams facilitate mutual updates in two instances, ensuring that both users receive consistent information drive across different messages.
00:26:11.440
Turbo Streams can also be applied to delivering notifications such as alerts, maintaining a dynamic user experience throughout various applications.
00:26:49.440
When it comes to broadcasting specific updates to users, create a channel dedicated to communicating real-time changes. This can enhance interactivity in various applications.
00:27:37.560
Now, I'm excited to transition to discussing Stimulus, which I deeply appreciate as a tool. I’ve always seen myself as a Ruby on Rails developer and avoided heavy reliance on JavaScript frameworks like React.
00:28:36.440
With Stimulus, I don't need to disable Turbo when loading JavaScript, providing a more integrated approach to development. I've effectively replaced numerous inline scripts with Stimulus, allowing for a cleaner structure.
00:29:37.520
For instance, in Basecamp’s examples, they’ve utilized live interactions elegantly. You can recreate project management functionalities in a new Rails application, such as task lists and draggable items, using libraries like SortableJS and RequestJS for database updates.
00:30:30.480
By leveraging external libraries and building your own Stimulus Controllers, you can create robust user interfaces without the encumbrances of more complicated frameworks.
00:31:01.599
Lastly, I want to encourage all of you to explore Hotwire. It creates a satisfying developer experience that aligns well with a back-end Ruby developer’s mindset. Thank you all for being here today.