stimulus

Stimulus: bulk selection + Turbo batch action

For batch operations, Stimulus can manage the UI state (select all, indeterminate checkbox) while Turbo submits a regular form. This keeps the server in charge of authorization and the UI simple.

Stimulus: copy-to-clipboard with fallback + selection

Copy buttons are deceptively tricky across browsers. This Stimulus controller uses the Clipboard API when available, falls back to execCommand, and provides a hook for “Copied!” UI.

Custom turbo_stream action tag: highlight an updated element

Turbo gives you a handful of built-in stream actions (append, replace, remove), but sometimes you want behavior like “replace then highlight”. You can implement this as a custom action: send a turbo-stream with action='highlight' and include a templat

Stimulus: autofocus the first invalid field after Turbo update

Turbo stream re-renders can drop focus, which is rough for accessibility. Use turbo:render to focus the first invalid field inside a specific container. This feels “native” and reduces user friction.

Stimulus: resilient confirmation for destructive actions

Turbo supports data-turbo-confirm, but sometimes you want a stronger confirmation step (type-to-confirm, extra context, multi-step). Stimulus lets you implement consistent confirmations without sprinkling JS across views.

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

Keyboard shortcut “command palette” modal (Hotwire-first)

A command palette feels like a SPA feature, but you can do it Hotwire-first: place a turbo_frame_tag 'modal' in the layout and load the palette HTML into it. A small Stimulus controller listens for meta+k and navigates the modal frame to /palette. The

Character counter for textareas with Stimulus

A character counter is small, but it removes uncertainty for users (especially when there’s a limit). I implement it with Stimulus so it stays reusable: attach to a wrapper, declare input + output targets, and compute remaining characters based on an

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

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.

Importmap setup for Stimulus controllers (Rails 7 style)

If you’re using importmap, a clean Stimulus setup matters: it keeps controllers discoverable and avoids mystery load order bugs. I pin @hotwired/turbo-rails and @hotwired/stimulus, then use controllers index discovery to register everything. The payof

Stimulus: nested fields add/remove without re-rendering

For nested forms, Stimulus can manage the DOM while Rails handles the final params. Use a hidden template + a unique timestamp key. This keeps the server-rendered form simple and avoids JS frameworks.