Turn Turbo on. Change nothing else.
Turbo Drive intercepts clicks on links to your own site. Instead of letting the browser navigate, it fetches the page itself, swaps the <body>, merges the <head>, and updates the address bar without a reload, so Back and Forward still work.
Same links. Same server. Same HTML. The server doesn't even know. In Rails this is the turbo-rails gem, on by default in a new app: one import in application.js, plus the view and model helpers you'll meet along the way.
Place your bet. Type a draft, then click About. Which of the four survive this time?
The process lived. The draft didn't.
Drive keeps the process: window, document, every script and stylesheet already loaded. It does not keep the elements. The textarea lived inside <body>, and the whole body was replaced.
Look at the response: only <body> is highlighted now. The <head> was merged: the tab title changed, but the stylesheet and script with the same URLs were left alone. That's where the speed comes from. Not from smaller HTML, but from not re-running your CSS and JavaScript on every click.
Tell Turbo what to carry across.
Give an element an id and mark it data-turbo-permanent. Before each render, Turbo finds the element with the same id in the new page and moves your existing node into its place. Listeners, typed text, everything.
<form id="composer" data-turbo-permanent>
One rule: the element has to exist on both pages with the same id. That's why the compose box sits in a dock at the bottom of every page. Flip the switch, type a draft, click About. The form with its own pin, ticked in blue pencil, is the one that travelled.
This is the same attribute you'd use for a music player, a chat sidebar, or anything that must not restart when the page around it changes.
Post something.
Drive handles forms the same way. It sends the POST itself, expects a 303 redirect back, follows it, and renders the page it lands on. Watch the wire: two round trips, no reload.
On the server this is the redirect_to you already write. Nothing changes.
def create
@message = Message.create!(message_params)
redirect_to messages_path, status: :see_other
end
While the request is in flight Turbo disables the submit button so a double-click can't double-post. Add data-turbo-submits-with="Posting…" and it swaps the label too.
Things you get without asking.
- A progress bar if a page takes longer than 500 ms. Style
.turbo-progress-baror hide it. - Prefetch on hover. Hover a link for 100 ms and Turbo fetches it before you click. Try it: hover About, watch the wire, then click.
- Opting out.
data-turbo="false"on a link, a form, or a whole container hands it back to the browser. - Non-GET links.
data-turbo-method="delete"plusdata-turbo-confirm="Sure?". Try delete on a message.
That's Drive. Now, three questions it raises: