hotwire

Stimulus for sprinkles of JavaScript interactivity

Stimulus adds JavaScript behavior to HTML without building SPAs. Controllers attach to DOM elements via data-controller. I use Stimulus for modals, dropdowns, form validation, autocomplete. Actions connect events to controller methods via data-action.

Copy-to-clipboard button with Stimulus

Copy buttons are everywhere (invite links, API keys, CLI commands). With Stimulus, I keep it tiny and resilient: use navigator.clipboard.writeText when available, and fall back to selecting a hidden input for older browsers. I also provide immediate f

A reusable respond_to block for turbo_stream + html

Once you’ve built a few Hotwire controllers, you notice the same respond_to shape repeated. I extract a small helper (a concern) that yields a respond_to block and centralizes the “default HTML redirect” pattern. This keeps controllers readable and re

Notifications dropdown that live-updates with Turbo Streams

For a notifications dropdown, I keep the list server-rendered and let Turbo Streams keep it fresh. The dropdown content sits in a turbo_frame_tag (so you can also navigate to a full notifications page), and the unread badge is a separate small target

Turbo Native bridge for mobile hybrid apps

Turbo Native allows building iOS and Android apps using Rails server-rendered HTML with native navigation chrome. The web views communicate with native code via a JavaScript bridge for features like push notifications, camera access, or native UI patt

Avoid caching sensitive pages in Turbo Drive

Turbo’s page cache is great until you have sensitive screens (account settings, billing) where the browser back button might show stale content. I handle this by setting cache-control headers and, for specific actions, disabling Turbo caching via turb

Turbo Frames: scoped navigation inside a sidebar

You can build rich UIs by scoping navigation to a frame (e.g., a sidebar). Links inside the sidebar update only that frame while the main content stays put. This is great for filters and settings panels.

Stimulus: keyboard shortcuts that work with Turbo navigation

Keyboard shortcuts improve power-user workflows, but they must survive Turbo navigation. Attach on connect/disconnect, avoid global leaks, and scope shortcuts to the page/component.

Turbo Streams: Create with prepend + HTML fallback

A good Hotwire endpoint responds to both Turbo and non-Turbo clients. Use respond_to and render a turbo stream that prepends the new record and updates flash/errors, while keeping an HTML fallback for crawlers, redirects, and manual testing.

Turbo Streams: custom action for flash messages

Flash updates are common enough to deserve a first-class stream action. Defining a custom turbo-stream action keeps views tidy: instead of repeating turbo_stream.update, you can write <turbo-stream action="flash">.

Turbo Stream form errors: replace only the form frame

Hotwire forms feel “native” when invalid submissions keep you in context. Replace just the form frame with errors and keep the rest of the page intact. Return 422 so clients and caches behave correctly.

Hotwire-friendly “sort by” links that replace only the list

Sorting is a great candidate for Turbo Frames: clicking “Newest” shouldn’t reload your whole page shell. I wrap the list in a frame (e.g., id='results') and make sort links target that frame. The controller reads params[:sort] and applies an order sco