Hotwire: The Demo

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to hot wire an umbrella for trio frameworks that implement the html of the wire approach to building modern web applications at its heart is turbo which gives you techniques for bringing the speed of a single page application without writing a lick of javascript this screencast will focus primarily on showing how turbo works but most applications will eventually need a few sprinkles of javascript to get the fidelity they need and for that purpose we have stimulus it's a modest javascript framework for the html you already have i'll briefly show how this works to supplement the turbo demonstration finally we have strata which provides bridge tooling for how the web and native parts of a mobile hybrid application built with hotwire talk to each other we're still working on polishing strata for release so this screencast will not cover it hotwire is what we've used to implement all of the front-end elements of hey.com the new email service by basecamp we're going to build a chat application using manila rails plus the hotwire rails integration gem which includes the full setup for turbo and stimulus the hot wire install command will turn on redis backing for handling web sockets with action cable at the import map needed for autoloading stimulus controllers and a few other tweaks the application will use two models room and message one room has many messages we'll use a full scaffold for the room model to give us the basic editing interface but only use the model generator for message since it needs much less we're going to connect room and message together without using any of hot wire to start this will give us a foundation flow for a admittedly cumbersome chat application which we can then use to level up with hot wire techniques one at a time for messages we'll have just two actions new to render the form to create a message and create to handle the form submission note we that we are also adding a partial template to encapsulate rendering of the message this partial is then rendered when showing the room relying on the conventional naming to tie them together this is all just standard one-on-one rail stuff but let's start the server and try it out hello rails here's our interface to create a new room then we create a couple of new messages for that room yes technically a chat system but not exactly a very dynamic or appealing one so let's introduce our first turbo feature frames turbo frames decompose pages into independent contexts which can be lazy loaded and scope interaction so when you follow a link or submit a form only the content of the frame changes rather than the entire page this allows you to keep the state of the rest of the page from changing making the app feel more responsive to be able to easily see how the frames work we'll call them out with a blue border now let's wrap the room name and ability to edit it inside a frame the turboframe tag goes around both the initial display including the edit link and the part of the edit page we want to appear within the frame we see our frame wrapped in blue and when clicking the edit link the form from the edit screen is presented within and upon submission it's replaced again with just the display if we go straight to the full page editing screen we can see it has both a header and navigation links parts we were emitting from the frame note that if we try to click a link within the frame that goes somewhere without a matching frame nothing happens we can solve this by adding a data turboframe attribute that points to underscore top to break out of the frame just like traditional html frames now the backlink works and the frame scopes the edit display loop then let's add the new message link into an inline but lazy loaded turboframe tag that also just for starters act on the whole page this frame will be loaded right after the page displays hitting the new message controller action we made earlier like with edit we wrap the relevant segment in the frame tag with a matching id which is how turbo knows how to plug out the right frame you can now see two requests when we load the room one for the page one for the lazy loader frame let's try to add a message it works but this only demonstrates that the frame was lazy loaded right now we're resetting the whole page upon submission of the new message form whereas with the room name frame you can edit and submit without changing the rest of the page state a real independent context you can see how the frame replacement happens by inspecting the response to edit rails knows when a request is coming from a frame so won't render the layout but that's just a nice to have optimization turbo will plug out just the matching frame regardless of whether the response is optimized or not as you can see here the header and links are ignored now let's turn to turbo streams they deliver page changes over websocket or in response to form submissions using just html and a set of crud like action tags the tags let you append or prepend to replace and remove any target dom element from the existing page they're strictly limited to dom changes though no direct javascript invocation if you need more than dom change connect a stimulus controller we'll add a turbostream response to the message creation action such that we can add the new message to the room page without replacing the whole page this template invokes the append action with the dom id of the target container and either full set of partial rendering options or just the record we wish to render which conforms to the naming conventions for matching to a partial now we can add messages to the page without resetting it completely the edit name form can stay open while we're doing this because new messages are added directly to the messages div the turbostream html is rendered directly in response to the form submission and tempo knows from the mime type to process it automatically but notice the input field isn't cleared we can fix that by adding a stimulus controller the new rail stimulus integration gem ships with an autoloader for your controllers this is done with an import map supported by es module shim and the unprocessed es6 controller code that's loaded by the browser directly via esm you can of course continue to use stimulus with your existing javascript bundler and transpiler but this gives you a taste of how far we're able to get with native browser controls now the stimulus controller we're going to add will be a dead simple way to reset the form after creating a new message it has just one method reset which we will call when turbo is done submitting the form via fetch the only novel part here compared to existing stimulus is how we'll audit load the controller at runtime using esm when the data controller attribute is spotted in the dom reload to pick up the new stimulus controller then let's add another message and voila the form is reset and the message added dynamically but how interesting is a chat app where you're just talking to yourself let's start a conversation with another window you'll see that new messages are only added live to the originators window on the other side we have to reload to see what's been said let's fix that the first thing we'll do is establish a websocket connection to the stream identified by the room we're in this is done with the turbo stream from tag using a tamper save signed identifier in the view you can see the connection has been made to the turbo streams channel running over action cable from the inclusion of this text let's send new messages to this stream by adding a broadcast call to the message creation this method call mirrors what we're already doing in the turbostream template just over websocket now now we can add a new message and see it appear in both windows but you'll see the originator sees double because the turbo stream responds from the form submission is still in place on the other side we can inspect the traffic on the action cable websocket and see that the very same message partial is being used to render the update over there wrapped in the same turbostream tag there we don't have a form submission so the message is only added once let's fix the double vision by removing the turbo stream returned in response to the form submission for now we'll just leave a note to document the dead end this will be without a cable connection and now all updates are sent only once we can also turbo stream deleting messages we'll add a similar model callback on destroy that triggers a remove broadcast sent to the same stream but instead of adding any ui let's try to invoke this flow from the console here you can see the destroy carried out then spot the broadcast sent using the turbostream remove action tag and call it again another line disappears from both browser windows you can also create a new message straight from the console and here you'll see the same turbostream append action with the same partial template as with all the other examples finally we can add a replace to happen when the message is updated this follows the same flow and completes the lifecycle of callbacks you'd normally respond to with stream updates let's invoke from the console whoops we have to reload our console instance to pick up the code change and here we go the last message in the chat has been updated but it can be even simpler if you want a full menu of basic lifecycle updates you can replace these three callbacks with a single broadcast 2 declaration you'll notice that this setup even uses async broadcast so rendering is done out of band by a job queue let's add this shortened form directly to changing the room as well since the room identifies the stream we can just use broadcasts then we'll extract the room display as its own partial so it'll match the conventions assumed by the callback render it in line and give it a dom id now you can edit the name in one window and instantly see it updated in the other so that's hotwire an alternative approach to building modern web applications without using much javascript by sending html instead of json over the wire we get to keep all our template rendering on the server which means writing more of our application in our favorite programming languages now let's have a quick look at how these techniques are used in a real life application we at basecamp launched our new email service hey.com this past summer and within 40 kilobytes of compressed javascript were able to deliver a full-featured modern and successful email app complete with native applications across all the major platforms powered by the same majestic monolith running on hotwire hay uses lazy loaded turboframes to fetch the reply later and set aside trays at the bottom of the inbox these trays change far less frequently than the inbox itself so they're excellent candidates to run on the different caching schedule they're loaded as soon as the initial page is loaded but will 302 when already cached when you hit them a second time we also use lazy loaded turbo frames for menus but these are not loaded until you access them for the first time once loaded you'll be hitting that browser cache on subsequent visits this technique is used for both the hay menu and the me menu both triggered by the detailed summary tag pairing the topic page uses even more lazy loaded turbo frames since the basic page is shared amongst all users on a company account for maximum cash efficiency and all per user specialization is therefore done with frames but let's focus just on the toolbar frame which is where you start a new reply when reply now is pressed that frame is replaced with a frame response of the new message page if we delete that response we again replace the frame with the toolbar barely any javascript needed for the whole interaction now let's go back and have a look at the screener the screen reactions are synchronized between browser windows just like in our chat demo application although we hear updates needed for different pages require unique responses so we simply remove the pending email from the screener upon clicking the button but we update both the screen of button and reveal the screened in email in the inbox on the other screen you'll see we're still using a slightly older turbo stream syntax here with a template tag as the head but we'll be changing to the latest api shortly lastly you'll see how frames and streams can interact when you set aside an email we remove it from the inbox then add it to the set aside tray in both browsers or windows at once the removal in the acting window is done via turbostream response to the action and then both windows have the set aside email added to the tray over websocket you can check out all the ways we've used hotwire to build hay by signing up for a free trial account all the javascript is available with source maps all the turbo interactions are sent in the clear so there's plenty to learn from and we welcome you to borrow or steal our stimulus controllers i hope you've enjoyed this quick tour of hotwire and turbo in particular please help us further develop all the frameworks as open source thanks
Info
Channel: Getting Real
Views: 23,693
Rating: undefined out of 5
Keywords: ruby on rails, html, javascript
Id: eKY-QES1XQQ
Channel Id: undefined
Length: 12min 55sec (775 seconds)
Published: Tue Dec 22 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.