question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Turbo 7.1 - Turbo stream not handled when using form is using URL dot notation turbo_stream format

See original GitHub issue

I have a form that does some live filtering using turbo streams in a form that does a requestSubmit() as you type. Since upgrading to Turbo 7.1 this approach seems to break and the browser renders the <turbo-stream> as text to the browser, instead of handling the turbo stream.

Downgrading to Turbo 7.0 it works fine.

Even when replacing with a submit button, the result is the same.

My UI: image

After typing:

image

The code I using to request the turbo stream:

        <%= form_tag vacancies_recruitment_applicant_path(@applicant, format: :turbo_stream),
                     method: :get,
                     data: {controller: "form", turbo_frame: "vacancy-search-result"} do |form| %>
          <input type="search" name="query"
                 placeholder="<%= t("common.placeholders.search") %>"
                 autocomplete="off"
                 data-action="debounced:input->form#submit"
                 class="form-control form-control-lg"/>
        <% end %>
      </div>

      <%= turbo_frame_tag "vacancy-search-result" do %>
        <%= render partial: "vacancies", locals: { vacancies: vacancies } %>
      <% end %>

I also noticed that the Turbo Frame header is not inside the request headers in my console, whereas Turbo 7.0 it was sent.

image

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
seanpdoylecommented, Dec 6, 2021

@acetinick thank you for sharing additional information.

I think I’ve answered my own questions:

However, the screenshot you’ve shared displays /recruitment/applicants/17968/vacancies.turbo_stream?query=a in the browser’s URL bar.

How is that URL being populated?

If it’s from the <form>, then you might have omitted a [data-turbo-action="advance"] declaration from somewhere in your code sample.

If you aren’t using data-turbo-action anywhere in your sample, then it seems that the <form> submissions is being handled outside of the <turbo-frame> you’re mentioning.

Since hotwired/turbo#437, Turbo guards <form> submissions against “external” submissions by calling locationIsVisitable, which calls isHTML. Failing that check results in a page-wide navigation, which explains how the browser’s URL bar is being populated by the navigation in spite of the <form> targeting a <turbo-frame>.

This is a somewhat known issue (related to hotwired/turbo#480 and hotwired/turbo#385).

With that being said, one immediate way to remedy the issue is to encode the request format as a query parameter instead of a URL parameter. For <a> elements and <form method="post"> elements, that would mean encoding [href="/vacancies?format=turbo_stream"] instead of [href="/vacancies.turbo_stream"] (or [action="..."] in the case of <form> elements).

For <form method="get">, encode the parameter as an <input type="hidden" name="format" value="turbo_stream">.

That would handle the quirk of Turbo treating /vacancies.turbo_stream as an external, non-HTML resource.

That should handle it for Rails applications, since the framework treats ?format=... the same as /path.format. If that’s not the case for your server-side framework, you can append the "text/vnd.turbo-stream.html" Content Type to the form submission’s Accept: header:

addEventListener("turbo:before-fetch-request", (event) => {
  if (event.target instanceof HTMLFormElement) {
    const { fetchOptions: { method, headers } } = event.detail

    if (method.match(/get/i)) {
      headers.Accept = [ "text/vnd.turbo-stream.html", headers.Accept ].join(", ")
    }
  }
})

Could you try one of those solutions out and report back with the results?

A (potentially user-facing) fix for this mechanism would also resolve https://github.com/hotwired/turbo/issues/185, and is worth exploring more deeply.

0reactions
n-studiocommented, Oct 7, 2022

@tleish My comment was not about data-turbo-stream being set by default.

My comment was about the Accept header being set to text/vnd.turbo-stream.html by default for all form with a get method, or at least the ones with a data-turbo-stream attribute.

Read more comments on GitHub >

github_iconTop Results From Across the Web

rails turbo_stream is not working on a rails 7 application
In my form I have the following. <%= form_with url: "/request_trial", method: :post, format: :turbo_stream do |form| %> <% ...
Read more >
Ruby on Rails #59 Hotwire Turbo Streams CRUD - YouTube
Just Enough Hotwire for Rails Developers with Yaroslav Shmarov | Open Source Every DayTEXT VERSION: ...
Read more >
Delete resource with turbo-stream requests - YouTube
rubyonrails #turborails # turbostream #crudwithturboHello FriendsIn this lecture, we will perform destroy actions in the users controller ...
Read more >
Turbo Drive Essentials - Akshay's Blog
Change the browser URL using the History API,; Request the new page using a fetch request; Render the response HTML by. replacing the...
Read more >
hotwire-turbo-express - npm Package Health Analysis - Snyk
All security vulnerabilities belong to production dependencies of direct and indirect packages. License: MIT. Security Policy: No.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found