DEV Community

David Boureau
David Boureau

Posted on • Originally published at saaslit.com

The simplest turbo-frame example

Content originally published here : https://saaslit.com/blog/ruby/the-simplest-turbo-frame-example

What is a turbo frame ?

A turbo frame is a node of the DOM that is able to be replaced by another, without refreshing the browser (when the user clicks on a button for example).

Think about the old days where you had to update the DOM through an ajax request (without a full page reload).

Unexplained (but short) answer

For those who already knows a little about Rails and Hotwire, and just want a quick check about syntax, here is the full (unexplained) answer :

# inside config/routes.rb
  post "full_list", to: "welcome#full_list"
Enter fullscreen mode Exit fullscreen mode
# inside app/controllers/welcome_controller.rb
class WelcomeController < DashboardController

  def full_list
  end

end
Enter fullscreen mode Exit fullscreen mode
<!-- inside app/views/welcome/index.html.erb -->
<turbo-frame id="view_more">
  <%= button_to "View all", full_list_path %>
</turbo-frame>
Enter fullscreen mode Exit fullscreen mode
<!-- inside app/views/welcome/full_list.html.erb -->
<turbo-frame id="view_more">
  <p>
    That's all! Nothing else to show.
  </p>
</turbo-frame>
Enter fullscreen mode Exit fullscreen mode

A little bit of context

Rails is well known for it's "convention over configuration" paradigm. With simpler words, it means "as long as you follow naming conventions, everything works".

When discovering new features like Turbo and Hotwire, "everything works" usually starts by "everything is buggy"

So I decided to put this article as a reference for people who begins with Turbo Frame.

The bare minimum conventions not be off the Rails.

Prerequisites

ruby -v  # 3.3.0
rails -v  # 7.1.3
bundle -v  # 2.4.10
node -v # 20.9.0
git --version # 2.34.1
Enter fullscreen mode Exit fullscreen mode

Before turbo frames

As (every Monday actually;), build the bare minimum files to play with Rails, by creating a route, an associated controller, and a view :

rails new myapp
cd myapp
Enter fullscreen mode Exit fullscreen mode

Then

# Create a default controller
echo "class WelcomeController < ApplicationController" > app/controllers/welcome_controller.rb
echo "end" >> app/controllers/welcome_controller.rb

# Create a default route
echo "Rails.application.routes.draw do" > config/routes.rb
echo '  get "welcome/index"' >> config/routes.rb
echo '  root to: "welcome#index"' >> config/routes.rb
echo 'end' >> config/routes.rb

# Create a default view
mkdir app/views/welcome
echo '<h1>turbo_frame tutorial</h1>' > app/views/welcome/index.html.erb

Enter fullscreen mode Exit fullscreen mode

Then create database,

bin/rails db:create db:migrate
Enter fullscreen mode Exit fullscreen mode

Then launch your local Rails server by typing :

bin/rails server
Enter fullscreen mode Exit fullscreen mode

You should see the title "turbo_frame tutorial" when opening your browser at localhost:3000

Minimalistic turbo_frame

Actually, there is a simpler example, that directly loads the content of a frame from a source.

But I didn't had the use case so far, so I'll show an example where the turbo_frame is shown after a button has been clicked.

More realistic and simple turbo_frame

Controller and route has nothing special, it's plain old Rails.

# inside config/routes.rb

  # add this line, below Rails.application.routes.draw do
  post "full_list", to: "welcome#full_list"
Enter fullscreen mode Exit fullscreen mode
# inside app/controllers/welcome_controller.rb
class WelcomeController < DashboardController

  def full_list
  end

end
Enter fullscreen mode Exit fullscreen mode

There is nothing special to do in the controller when using turbo_frame

Now the interesting part

<!-- inside app/views/welcome/index.html.erb -->
<!-- add these lines below the h1 title -->

<turbo-frame id="view_more">
  <%= button_to "View all", full_list_path %>
</turbo-frame>
Enter fullscreen mode Exit fullscreen mode

Notice that the turbo-frame element is a HTML custom element.

It's coming from Turbo, so you don't have to define it yourself.

Use <turbo-frame id=""> and not <div id=""> if you want frames to update your DOM.

<!-- inside inside app/views/welcome/full_list.html.erb -->
<turbo-frame id="view_more">
  <p>
    That's all!
  </p>
</turbo-frame>
Enter fullscreen mode Exit fullscreen mode

Use .html.erb extension, and not turbo_stream.html.erb
{: .prompt-tip }

Use the exact same <turbo-frame> id inside the returned partial.

To sum up,

All you have to do is to take care about file and folder naming conventions, and Rails will take care about updating the right element of the DOM.

Checking the code

Relaunch your local web server, and refresh the browser at localhost:3000

When you click the button, you should see "That's all", instead of the button. If this doesn't work, you probably missed something in the above steps :)

Don't forget to check the network request inside the web developer tools of the browser, in order to grab what is going on.

Summary

Turbo frame is some kind of weird name, for a very old and simple concept : update the DOM after a user action.

When following convention properly, Rails handles this for you very nicely :)

Top comments (0)