stimulus

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 controller for drag-and-drop file uploads

Modern file uploads should support drag-and-drop in addition to traditional file inputs. I use Stimulus to handle dragover, drop, and paste events, showing upload previews and progress. The controller prevents default browser behavior for drag events

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.

Hotwire Turbo for SPA-like user experiences

Hotwire Turbo delivers SPA speed without JavaScript complexity. Turbo Drive accelerates navigation by replacing page body without full reload. Turbo Frames update page sections independently—click a frame link, only that frame refreshes. Turbo Streams

Stimulus controller for dependent select dropdowns

Dependent dropdowns are a classic UX pattern where one select populates based on another's value. With Stimulus, I handle this entirely client-side after the initial page load by storing options as data attributes or fetching them via AJAX. When the p

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

Infinite scroll with Turbo Frames and Intersection Observer

Infinite scroll improves perceived performance by loading content as users reach the bottom of the page. I combine Turbo Frames with the Intersection Observer API via a Stimulus controller. The last item in each page has a sentinel element that, when

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