erb

javascript
import { Controller } from "@hotwired/stimulus"
import { DirectUpload } from "@rails/activestorage"

export default class extends Controller {
  static targets = ["input", "preview", "status"]
  static values = {

Stimulus controller for drag-and-drop file uploads

stimulus javascript file-uploads
by Jordan Lee 2 tabs
ruby
class ActivityPanelController < ApplicationController
  def show
    @project = Project.find(params[:project_id])
    @events = @project.events.order(created_at: :desc).limit(50)

    latest = @events.maximum(:updated_at)

ETag + last_modified for expensive Turbo Frame endpoints

rails hotwire turbo
by Henry Kim 2 tabs
ruby
class Comment < ApplicationRecord
  belongs_to :post
  belongs_to :author, class_name: 'User'

  # Automatically broadcast changes to all subscribers of this post
  after_create_commit -> { broadcast_append_to post, target: "comments" }

Turbo Stream broadcasts for real-time collaboration

hotwire turbo-streams actioncable
by Jordan Lee 3 tabs
ruby
class DashboardWidget < ApplicationRecord
  broadcasts_refreshes
end

Broadcasts refreshes for complex pages (less target wiring)

rails hotwire turbo
by Henry Kim 2 tabs
ruby
class PostsController < ApplicationController
  def create
    @post = current_user.posts.build(post_params)

    if @post.save
      flash[:success] = 'Post was successfully created.'

Rails Flash messages for user feedback

rails flash messages
by Maya Patel 2 tabs
erb
<nav class="flex gap-2">
  <%= link_to 'Profile', settings_path(tab: 'profile'), data: { turbo_frame: 'tab_content' } %>
  <%= link_to 'Billing', settings_path(tab: 'billing'), data: { turbo_frame: 'tab_content' } %>
</nav>

<%= turbo_frame_tag 'tab_content' do %>

Tabs UI using Turbo Frames (no client router)

rails hotwire turbo
by Henry Kim 2 tabs
ruby
class Message < ApplicationRecord
  belongs_to :room
  broadcasts_to ->(message) { [message.room, :messages] }, inserts_by: :prepend
end

Declarative model broadcasts with broadcasts_to (Rails 7)

rails hotwire turbo
by Henry Kim 2 tabs
javascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["field"]

  connect() {

Stimulus: autofocus the first invalid field after Turbo update

rails stimulus hotwire
by codesnips 3 tabs
ruby
respond_to do |format|
  format.turbo_stream
  format.html { redirect_to projects_path, notice: 'Created.' }
end

Turbo Streams fallback to HTML for older clients

rails hotwire turbo
by Henry Kim 2 tabs
ruby
class WizardsController < ApplicationController
  before_action :load_draft

  def step_1
    render_step(1)
  end

Hotwire-powered multi-step forms

hotwire turbo forms
by Jordan Lee 3 tabs
erb
<article class="post">
  <h1><%= @post.title %></h1>
  <%= simple_format @post.body %>

  <!-- Lazy load comments when scrolled into view -->
  <%= turbo_frame_tag "post_#{@post.id}_comments",

Lazy-loading Turbo Frames for performance

hotwire turbo performance
by Jordan Lee 3 tabs
css
.confirm-dialog {
  border: none;
  border-radius: 12px;
  padding: 1.5rem;
  max-width: 26rem;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);

Stimulus: resilient confirmation for destructive actions

rails stimulus hotwire
by codesnips 3 tabs