Hotwire: Turbo Frames

Tubo Frames decompose your page in parts using tag <turbo-frame>, which can be replaced by copies received by the server, just locating and replacing them thanks to identifiers. For example we can manage a message in your list of messages annotating with this tag “_message.html.erb”:

<%= turbo_frame_tag @message do %>
  <%= link_to @messages, data: { turbo_frame: "_top" } %>
<% end %>

In this ERB code frame would be replaced inside the tags, but the link to all messages will be replaced in full body of HTML page. Here is the translation to HTML code:

<turbo-frame id="message_1">
  <a href="/messages" data-turbo-frame="_top" />

In controller we send only “_message.html.erb” rendered

def show
  @message = Message.find(params[:id])
  render @message

Eager-loaded frame: Replaced when “/messages” are loaded. Adding “src: @messages” to your ERB file.

Lazy-loaded frame: Content will be replaced when frame is visible. Add [loading: “lazy”]to ERB tag

Frame targets: manage where to be replaced

  • [target: “_top”]: All links/forms within replace full window.
  • [target: “main”]: All links/forms within replace “main” frame.
  • [data: {turbo_frame: “_seld”}]: In a “_top” frame resets the link to self replacement.

Advance/replace on browser history: By default takes replace strategy, but you can create copies: <turbo-frame data-turbo-action=”advance”>

Anti-forgery support (CSFF):

  • Auto managed by Rails, adds a <meta> in header with “csrf-token” name attribute.
  • Then all submissions send “X-CSRF-TOKEN” in HTTP header. Except when: data-turbo=”false”; which disables turbo in this element.

Several Frame attributes and JavaScript properties:

  • src (Frame.src in JS): path to control the navigation URL.
  • loading (Frame.loading): navigation eager or lazy.
  • disabled (Frame.disabled): Frame disabled for navigating.
  • autoscroll (Frame.autoscroll): Scroll after loading. Values are: end|start|center|nearest.

Check reference, they are very useful on development.

Leave a Reply

Your email address will not be published. Required fields are marked *