Cesare Ferrari

July 21, 2022

Working with Turbo Frames in a Rails application



Turbo frames let you divide an HTML page into discrete sections that can be updated independently from the rest of the page.
These sections are represented by turbo-frame custom HTML elements with unique id attributes.

To create turbo-frames we use the turbo_frame_tag helper in a Rails view with a syntax similar to this:

  <%= turbo_frame_tag "hello" do %>
    <%= link_to "Say Hello", "/hello" %>
  <% end %>

This will create the following turbo-frame element on the HTML page:

<turbo-frame id="hello">
    <a href="/hello">Say Hello</a>
</turbo-frame>

Note that the first argument passed to the turbo_frame_tag helper becomes the turbo-frame element id.

Using Turbo frames

We already know that Turbo Drive intercepts link clicks and form submissions and transforms them into Ajax requests to the server.

Turbo Drive will also examine the response returned by the server. If the response has a turbo-frame element with the same id as the one containing the link (or form) that originated the request, Turbo Drive will replace the originating turbo-frame element with the turbo-frame element contained in the response that has the same id.

So, if the originating turbo-frame id is “hello”, Turbo Drive will look for a turbo-frame with id “hello” in the response and substitute the contents of the originating element with the contents in the response.

Here’s an example to illustrate this.

In our application we have a Welcome controller, with two actions: index and hello.

# app/controller/welcome_controller.rb

class WelcomeController < ApplicationController
  def index
  end

  def hello
  end
end

The view for the index page has the originating turbo-frame element with a link to the hello action:

# app/views/welcome/index.html.erb

<%= turbo_frame_tag "hello" do %>
    <%= link_to "Say Hello", "/hello" %>
  <% end %>

When we click on the the “Say Hello” link, the WelcomeController#hello action is invoked and the server responds with the app/views/welcome/hello.html.erb template.

This template has a turbo-frame element with the same id as the originating element:

# app/views/welcome/hello.html.erb

<%= turbo_frame_tag "hello" do %>
  <p>Welcome to my site</p>
<% end %>

Turbo Drive finds this turbo frame element in the response and substitutes the originating turbo-frame element in the index page with the content of the turbo-frame element in the hello page.

The result is that clicking on the link results in its replacement by the string “Welcome to my site”.

In future posts I will go into more details about Turbo frames. 

Check out my site at www.ferrariwebdevelopment.com for more insights.