Custom confirm dialog with Stimulus (better than window.confirm)

data-turbo-confirm uses the browser confirm dialog, which is functional but not pretty. For a more polished app, I replace it with a Stimulus controller that intercepts clicks, shows a custom modal, and only proceeds if the user confirms. Turbo makes

Frame navigation that targets a specific frame via form_with

Sometimes a form submission should update a specific section rather than navigate the whole page. With Turbo, this is as easy as setting data-turbo-frame on the form. For example, a filter form can target a results frame, so submissions replace only t

Fragment caching inside Turbo Frames (fast lists)

Hotwire doesn’t replace caching—it makes it more valuable because you’re sending HTML frequently. I use fragment caching inside list partials and keep cache keys stable with cache blocks. The pattern is: cache each row by record, and cache the list wr

Lazy-load heavy panels with IntersectionObserver + Turbo frame

Not every part of a page needs to load immediately. For heavy panels (analytics charts, audit logs), I use a Turbo Frame with src and a tiny Stimulus controller that sets the src when the element becomes visible via IntersectionObserver. This avoids f

Admin “quick toggle” with Turbo Streams and a single partial

Admin toggles (published/unpublished, featured/unfeatured) are a perfect Hotwire use case: server-rendered state, instant UI update. I render the toggle as a partial inside a frame, and the update action responds with a turbo stream replacing that fra

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

Declarative model broadcasts with broadcasts_to (Rails 7)

When I’m on Rails 7+, I like broadcasts_to because it makes realtime behavior obvious in the model. Instead of writing explicit after_create_commit hooks, I declare that a model broadcasts to its parent or to a scope. Then Turbo uses conventional part

Autosave drafts with Stimulus + Turbo (lightweight)

For long text entry, autosave is a huge quality-of-life improvement. I implement it with a Stimulus controller that debounces input and submits the form to a drafts endpoint in the background. The response is a turbo stream that updates a “Saved at …”

Inline markdown preview using Turbo Frames

A markdown preview doesn’t need a client markdown parser. I render the preview server-side (same pipeline used in production), and load it into a Turbo Frame. The editor form includes a frame called preview, and a “Preview” button submits the form to

Reorder a list server-side and reflect instantly with Turbo Streams

Drag-and-drop reorder can be fancy, but the core is: user triggers a reorder action, server persists positions, and the UI updates. For simpler UIs, I skip drag-and-drop and use up/down buttons. Each click POSTs to a move_up action, updates position,

Disable submit button while Turbo form is submitting

Double-submits are easy to trigger on slow connections, especially with Turbo where the page doesn’t visibly reload. I add a Stimulus controller that listens to turbo:submit-start and turbo:submit-end events on the form. On submit start, disable the s

Autofocus first input when a Turbo modal opens (Stimulus)

A modal that opens without focusing an input is a tiny annoyance that adds up. In Hotwire apps, modals often swap in via Turbo Frames, which means the DOM is injected after navigation. Stimulus is ideal here: attach an autofocus controller to the moda