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 frame not replaced when at root of an HTML fragment

See original GitHub issue

First, I am using this version of Turbo from the CDN.

https://unpkg.com/@hotwired/turbo@7.1.0/dist/turbo.es2017-umd.js

Let’s say I have a basic form within a frame with only a submit button.

<h1>Turbo Frame example</h1>

<turbo-frame id="results">
  <p>Use the following button to replace the frame</p>
  <form action="/turbo/search" method="post">
    <input type="submit" value="swap">
  </form>
</turbo-frame>

When I click the button, the POST request is made to /turbo/search. In the response from the server, I return a fragment of HTML (without any layout or anything) containing a h1 followed by the matching frame. Everything is ok so far and the initial frame gets replaced.

Response is:

<h1>Full list of results</h1>

<turbo-frame id="results">
  <ul>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ul>
</turbo-frame>

And Turbo changes the page to:

<h1>Turbo Frame example</h1>

<turbo-frame id="results">
  <ul>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ul>
</turbo-frame>

Now, if I decide to remove the h1 and only return the frame as the response, it does not get swapped. Nothing happens, and I don’t have any message in the console. It feels like Turbo does not know how to extract the frame from the response if this response is the frame.

Am I doing something wrong or is it a known behavior? Thanks

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
lobrecommented, Dec 9, 2021

This makes total sense. Sorry for opening an issue that isn’t one!

Thanks a lot for your exploration and for having found the root cause.

For reference and for those who use Go and fall into this issue, the package net/http in stdlib tries to detect the content type when not set explicitly.

This is done in DetectContentType.

For “full” HTML documents, it works consistently. I also never had any issues when rendering partial HTML documents. But the problem here with Turbo is that <turbo-frame> isn’t recognized as a standard HTML tag, and this makes the detection fail.

Hence the need to explicitly set text/html.

Here is the fix in my example repo (I will keep it public in case anyone needs that). I also published the fix under a release v0.0.2.

https://github.com/lobre/go-turbo-frame/commit/6b42ae553d12338dd7a7978f1fce66cb5ebc2b97

1reaction
lobrecommented, Dec 7, 2021

Is the response a 200 OK that renders the HTML fragment, or a 3xx redirect to a page that renders the HTML fragment?

Sorry I haven’t given those details. It returns a 303 redirect to /turbo/results (which gets executed by the browser and succeeds with a 200). And this result page is the one returning the fragment (which is what I should be doing of what I see in the docs). And again, it works perfectly if I add anything outside the frame in the returned HTML fragment.

I have also just tested with an anchor (<a>) instead of a form, and I have the same behavior. The server directly returns a 200 with the fragment but the frame won’t swap if the result only contains the matching frame.

<h1>Turbo Frame example</h1>

<turbo-frame id="results">
  <p>Use the following button to replace the frame</p>
  <a href="/turbo/results">link to results</a>
</turbo-frame>

In both of those cases, I never use Streams. I don’t return any, and I don’t set text/vnd.turbo-stream.html on the response.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Turbo frame content not replaced - Hotwire Discussion
I'm trying to make the basic frame example from the handbook work, unfortunately without success so far. Probably some very obvious mistake ...
Read more >
Turbo Stream in Hotwire - Robert Guiscard - Medium
Turbo Stream allows you to construct HTML with all the facilities from Rails and transfer the final fragment to the front end. While...
Read more >
Documentation for turbo-rails (1.0.0) - RubyDoc.info
It lets you carve up a page into independent frames, which can be ... the turbo frame will be replaced with the one...
Read more >
Micronaut Views - GitHub Pages
You can render a Turbo Frame easily by annotating a controller route with TurboFrameView and returning only the HTML used by Turbo. <turbo-frame...
Read more >
Phoenix on Turbo - Hostile Developer
FRAMES ! Turbo Frames let you compose web pages from several endpoints, ... Turbo Streams allow you to send fragments of html via ......
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