turbo

Optimistic UI updates with Turbo Streams

Waiting for server confirmation makes interfaces feel sluggish. Optimistic updates immediately show the expected result, then reconcile with the server response. When a user likes a post, I increment the count immediately via Stimulus, submit the requ

Typing indicator via ActionCable + Turbo Streams

Typing indicators can be done without a complex protocol. I broadcast a small turbo stream replace to a typing_indicator target when a user starts typing, and another replace to clear it after a timeout. On the client, a Stimulus controller sends “typ

Turbo Frame modal that renders server HTML

When I need a modal (new/edit/show), I avoid client-side templating by using a dedicated turbo_frame_tag as the modal container (often id='modal'). Links target that frame, so the response only replaces the modal content. Closing the modal is just swa

Turbo Drive: disable caching on volatile admin pages

Turbo Drive caches pages aggressively, which is usually great. For volatile admin dashboards (counts, queues, toggles) you often want no-cache to avoid confusing “stale UI” bugs. turbo_cache_control makes the intent explicit.

Broadcast a status badge update on background processing

A lot of Rails apps have records that transition through states: queued, processing, done. With Hotwire, I render a status badge partial and broadcast replacements when the state changes. A background job updates the record, and the model broadcasts a

Stimulus: debounced search that plays nicely with Turbo

Client-side debounce is best done in Stimulus (not in view helpers). This controller submits the nearest form after a short pause, while letting Turbo handle the navigation and frame replacement.

Customize Turbo progress bar styling with Tailwind/CSS

Turbo includes a progress bar at the top of the page, and it’s a surprisingly visible part of perceived quality. I like to set the color and height to match the app’s brand. This is pure CSS: target .turbo-progress-bar. You can also make it slightly t

Keep navbar state across Turbo navigations with data-turbo-permanent

Some UI elements should survive navigation: a music player, a search input, or a navbar with an open dropdown. Turbo’s data-turbo-permanent lets you mark a DOM node that shouldn’t be replaced during visits. I use it carefully—permanent nodes can keep

Inline create form that prepends into a list with Turbo Streams

My favorite Hotwire demo is the classic “inline create” on an index page. The form sits at the top of the page. When submitted, the create action returns turbo streams that (1) prepend the new item into the list and (2) replace the form with a fresh,

Turbo Streams for real-time list updates

Turbo Streams enable surgical DOM updates from the server without writing JavaScript. After a successful form submission, instead of redirecting, I return a Turbo Stream response that appends, prepends, replaces, or removes specific elements. This is

Scoped navigation inside a sidebar with Turbo Frames

Sometimes you want only part of the screen to navigate—like a sidebar list updating the main content. Turbo Frames can do this cleanly: render the sidebar normally, and make its links target a turbo_frame_tag called main. Clicking a link swaps the mai

Turbo Frames: inline “details drawer” without a SPA router

A common UI is a list on the left and a details panel (drawer) on the right. With Turbo Frames, each list item link can target a details frame. Clicking an item swaps the drawer content while leaving the list intact. The server still renders HTML, so