hotwire

ruby
class PostsController < ApplicationController
  def index
    @posts = Post.published
                 .order(created_at: :desc)
                 .page(params[:page])
                 .per(20)

Infinite scrolling list using lazy Turbo Frames

rails hotwire turbo
by codesnips 4 tabs
ruby
module LayoutlessTurboFrame
  extend ActiveSupport::Concern

  included do
    layout :layout_for_turbo
  end

Render without layout for Turbo Frame requests

rails hotwire turbo
by codesnips 4 tabs
ruby
class TurboFailureApp < Devise::FailureApp
  def respond
    if turbo_request?
      redirect_for_turbo
    else
      super

Handle 401 responses in Turbo by forcing a full redirect

rails hotwire turbo
by codesnips 4 tabs
javascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["input", "results"]
  static outlets = ["results-list"]
  static values = {

Stimulus outlets for inter-controller communication

stimulus javascript architecture
by Jordan Lee 3 tabs
ruby
class NotificationsController < ApplicationController
  def mark_all_read
    current_member.notifications.unread.update_all(read_at: Time.current)

    streams = Turbo::Streams::TagBuilder.new(view_context)

Build Turbo Stream responses in the controller (TagBuilder)

rails hotwire turbo
by Henry Kim 2 tabs
erb
<div id="save_state" class="text-xs text-gray-500">Not saved yet</div>

Turbo Streams: inline “saved” indicator that updates on autosave

rails hotwire turbo
by Henry Kim 2 tabs
erb
<div id="image_preview">
  <%= render 'images/preview', record: @profile %>
</div>

Preview Active Storage uploads after attach using Turbo Streams

rails hotwire turbo
by Henry Kim 3 tabs
erb
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>

<div class="posts-index">
  <div class="sticky top-0 bg-white border-b" id="search-bar">
    <%= form_with url: posts_path, method: :get, data: { turbo_frame: "_top", turbo_action: "morph" } do |f| %>
      <%= f.search_field :q,

Morphing page updates with Turbo Morphing

hotwire turbo morphing
by Jordan Lee 2 tabs
ruby
class PostsController < ApplicationController
  def new
    @post = Post.new
  end

  def create

Inline markdown preview using Turbo Frames

rails hotwire turbo
by codesnips 4 tabs
erb
<%= form_with url: autosave_draft_path,
              method: :post,
              local: false,
              data: {
                controller: "autosave",
                autosave_target: "form",

Autosave drafts with Stimulus + Turbo (lightweight)

rails hotwire stimulus
by codesnips 3 tabs
ruby
class Recipe < ApplicationRecord
  has_many :ingredients, inverse_of: :recipe, dependent: :destroy

  accepts_nested_attributes_for :ingredients,
    allow_destroy: true,
    reject_if: :all_blank

Add/remove nested fields with Stimulus (no cocoon)

rails hotwire stimulus
by codesnips 4 tabs
erb
<!DOCTYPE html>
<html>
  <head>
    <title>Contacts</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

Turbo Frames modal: load, submit, then close via stream

rails turbo hotwire
by codesnips 4 tabs