20 · Turbo Frames

Click edit on a message.

With Drive, that's a visit. The whole body becomes the edit page. It's fast, it's fine, and it's not what you wanted. You wanted the form to appear where the message was, with the rest of the page left alone.

Frames are the answer to "navigate, but only in here."

→ click edit on any message
20 · scoped navigation

Wrap it in a frame.

<%= turbo_frame_tag message do %>
  <%= render message %>
<% end %>

<!-- renders as -->
<turbo-frame id="message_2">…</turbo-frame>

A frame captures every link and form inside it. Click edit now. The request goes out with a Turbo-Frame: message_2 header. The server sends back the full edit page, and Turbo keeps only the <turbo-frame> with the matching id. Everything else in the response is thrown away.

→ switch it on, click edit
20 · the dual-purpose page

The edit page is still a real page.

Click the address bar, replace the path with /messages/2/edit, press Enter. You get a full page with a heading. Same template, same controller action, nothing special-cased.

<%# messages/edit.html.erb %>
<h1>Editing message</h1>

<%= turbo_frame_tag @message do %>
  <%= render "form", message: @message %>
<% end %>

Only the part inside the frame tag gets used when the request came from a frame. The heading is outside, so it stays out. You write one view; it works as a page and as a fragment. This is the habit frames want from you: name the region, and put the same id on both sides.

20 · forms in frames

Now save it.

Click edit, change the text, press Save. Watch the wire: PATCH, then a 303 back to /messages, then a GET. The frame follows the redirect, fetches the messages page, and pulls its own id out of it again.

On the server that's the ordinary update action: save, redirect_to messages_path. Nothing on the server knows a frame was involved. The frame did the rest.

Scroll and uptime survived. Nothing outside the frame was touched.

→ edit, change the text, save
20 · what frames raise

Three things every frame user runs into.

Each one lives on a specific part of the frame. Pick the one bothering you; you'll come back here.

The response had no matching frame"Content missing" →
src="/related" on an empty frameframes that load themselves →
A link inside that should leavebreaking out →

And the limit that leads to the next rung: a frame can only change itself. What if the form were inside a frame too, and posting had to update the counter up in the nav bar?