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

Tabs UI using Turbo Frames (no client router)

Tabs often turn into a mini-SPA. Instead, I treat each tab as a URL and load its content into a turbo_frame_tag named tab_content. Clicking a tab link targets that frame. This gives you browser history, deep linking, and sharable URLs, while keeping t

Request spec: Turbo Stream template is rendered

For controller-level confidence, I add a request spec that sets Accept: text/vnd.turbo-stream.html and asserts the response includes a turbo stream action. This is faster than a system test and catches accidental template name changes (create.turbo_st