Turbo 8 FAQ
Questions I ran into working with Turbo Frames and Turbo Streams.
How can I update multiple turbo_frames in one response?
- DHH: “If you want to replace multiple frames, you can also just target
_top
and replace the whole thing via drive. But otherwise there won’t be a path to custom replace two frames. When you need that, you gotta go to turbo streams.”- But
_top
may be heavy because it reloads everything.
- But
- cryptogopher: “You can nest turbo streams inside turbo frame […]”
- For my use case, I went with this solution. This means you don’t need to have multiple turbo-frames, just one, which targets other parts of the page via turbo streams by id.
More advice in this issue’s comments.
Can I make a lazy turbo_frame request a turbo_stream from the server?
There are hacks, but it’s not the intended use case. Just include turbo stream tags into the turbo frame response. (See “How can I update multiple turbo_frames in one response?”)
How to get button_to
inside turbo_frame
to reload page?
Set target: '_top'
on the turbo_frame
.
How to preserve scroll on a link with changing GET parameter?
Add data-turbo-action="replace"
attribute to the link. Source
When to use turbo_frames, custom turbo_stream actions, automatic turbo_stream_from, and nothing?
This is my current understanding, updated as it evolves.
- Nothing: Most of the time nothing is needed, because transitions between pages are all happening with Turbo drive (body replacement). Redirects back to the same page after
create
,update
, ordestroy
are handled via PageRefreshes in Turbo 8 automatically using morphing (as long as redirect destination url matches where request was submitted from). All that’s needed is the meta tag<%= turbo_refresh_method_tag :morph %>
. Controllers can just contain redirects back to where they came from, and it will work with no additional effort. - Turbo Frames: Due to the new PageRefreshes, turbo frames are less needed now, but are still useful for lazy-loading (with
loading: lazy
). For example, when parts of page are inlined directly from 3rd party API. They used to be the primary way of updating parts of the page, before page refreshes with morphing became a thing. - Custom turbo_stream actions: Custom turbo_stream actions are almost never needed anymore, because PageRefreshes do that well enough. They’re only useful in 2 cases: 1. if you need a very granular lightweight way to update specific pieces of the page (where full page refresh is too expensive for every update). 2. Where you used turbo_frame with lazy loading, but you want to update a few pieces of the page that fall outside of the loaded frame. You can supply turbo_stream actions inside that turbo_frame. (See “How can I update multiple turbo_frames in one response?”)
- Automatic turbo_stream_from: For pages that need refreshing when something changed in the persisted data, e.g. background jobs or other requests updated a model, that model’s
broadcast_refreshes
and view’sturbo_stream_from
is the simple way to handle that. The downside is that you need ActionCable (websocket infra) for this.
Resources:
- https://blog.theleafnode.com/turbo-8-page-refresh/
- https://dev.37signals.com/a-happier-happy-path-in-turbo-with-morphing/