Turbo Not Accepting Turbo Stream

Hello!

I am roughly following an example I found here and running into some issues: ChatGPT streaming with ruby-openai, Rails 7, Hotwire, Turbostream, Sidekiq and Tailwind! · GitHub (a major difference is I have a model and controller callled ChatMessage not just Message and my Model has a field called message in place of content)

I’m currently having an issue where submitting the form causes the browser to redirect to the Turbo stream response (as plain text) instead of placing it in the frame. I think this is because Turbo is not adding text/vnd.turbo-stream.html to the Accept request header when submitting the form or it is not interrupting the form/preventing default handling. Rails correctly responds with a text/vnd.turbo-stream.html response.

I can’t figure out/find documentation for how to really debug or log anything with Turbo in the browser/JavaScript side. I can confirm that Stimulus is working fine elsewhere in my app (so JS is loading), and Turbo-based navigation/redirects between pages (the default functionality from Rails scaffold that doesn’t require additional setup) is working fine.

I have a form that looks like:

<%= turbo_frame_tag "#{dom_id(chat)}_chat_message_form" do %>
  <%= form_with(model: ChatMessage.new, url: chat_chat_messages_path(format: :turbo_stream)) do |form| %>
    <div class="my-5">
      <%= form.text_area :message, rows: 4, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full", autofocus: true, "x-on:keydown.cmd.enter" => "$event.target.form.requestSubmit();" %>
    </div>

    <div class="grid justify-items-end">
      <%= form.button type: :submit, class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" do %>
        <i class="fas fa-paper-plane"></i>
        <span class="pl-2">Send</span>
      <% end %>
    </div>
  <% end %>
<% end %>

I needed to change the URL from url: [chat, chat.chat_messages.new] to chat_chat_messages_path(format: :turbo_stream) or I would get an ActionController::UnknownFormat error from Rails.

I tried adding data: {turbo_stream: true} or data: {turbo_stream: true, turbo_frame: "#{dom_id(chat)}_chat_message_form"} to the form_with to no effect.

Rails 7.1.1 turbo-rails 1.5.0 @hotwired/turbo-rails 7.3.0

Controller:

class ChatMessagesController < ApplicationController
  include ActionView::RecordIdentifier

  before_action :authenticate_user!

  def create
    @chat_message = ChatMessage.create(chat_message_params.merge(chat: Chat.user_last_chat(current_user), role: "user"))

    GetAiResponse.perform_later(@chat_message.chat_id)

    respond_to do |format|
      format.turbo_stream
    end
  end

  private

  def chat_message_params
    params.require(:chat_message).permit(:message)
  end
end

create.turbo_stream.erb:

<%= turbo_stream.append "#{dom_id(@chat_message.chat)}_chat_messages" do %>
  <%= render "chat_message", chat_message: @chat_message, scroll_to: true %>
<% end %>
<%= turbo_stream.replace "#{dom_id(@chat_message.chat)}_chat_message_form" do %>
  <%= render "form", chat: @chat_message.chat %>
<% end %>

routes.rb:

resource :chat, only: [:create, :new, :current_chat], as: :current_chat do
  member do
    # Some other paths here as well
    resources :chat_messages, only: [:create], as: :chat_chat_messages
  end
end

I’m really stumped on this! Any help is much appreciated!

I think I needed to change this because Turbo is not catching the submit event. I’m not sure how to debug that–I don’t have any additional JS besides what Rails scaffolded (including Bootstrap) and some Stimulus controllers that don’t appear on this page.

Figured it out! See here: Turbo ignores form ending with action ending in parameter · Issue #1069 · hotwired/turbo · GitHub