Accelerating with Turbo Drive
Notes
Code Snapshot
A snapshot of where the code stands at the end of the video is in the 04-turbo-drive
directory of the code bundle.
🤔 Turbo Drive Not Enabled?
In the video, we enabled Turbo Drive by commenting out the following line in application.js
:
Turbo.session.drive = false
After saving that file and then reloading the "Baits" page, we saw that clicking the "Tackle Box" link sends an asynchronous fetch request. That's how you know Turbo Drive is enabled.
If instead you're seeing regular HTTP requests, then it's likely because changing application.js
file didn't generate a new JS bundle. Make sure you're running the Rails server using ./bin/dev
which, among other things, generates a new JS bundle whenever application.js
changes.
Ready to Start Hotwiring Your App?
At some point you'll likely want to start introducing facets of Hotwire into your own app. If you're using Rails 7 then you're good to go since Hotwire is installed and configured out-of-the-box. If you're using Rails 6, however, then you'll need to install Hotwire manually.
Displaying Page Load Progress
When navigating around the app, did you notice the browser didn't display its native load progress indicator? Go ahead, give it a try. Indeed, with Turbo Drive handling all the page navigation, the browser doesn't provide any feedback while pages are being loaded.
But it's important to give users some sort of feedback that a page is loading, especially if takes a while. So Turbo Drive includes a CSS-based progress bar that appears automatically for any page that takes longer than 500ms to load. ⏱
Running this app locally, it's fast enough that you may never see Turbo Drive's progress bar. And that would be a shame. Thankfully, the delay is configurable and there's an easy way to set it. Simply add this line to your app/javascript/application.js
file:
Turbo.setProgressBarDelay(1)
This sets the progress bar delay to 1ms. So now you'll see it on every page load as you navigate around the app.
Want to style the progress bar to be on-brand with the rest of your site? No problem. The progress bar is a <div>
element with the class name turbo-progress-bar
. You just need to write a CSS rule that targets that element. For example:
.turbo-progress-bar { height: 10px; background-color: PeachPuff; }
Once you've played around with this, don't forget to set the progress bar delay to something reasonable, or just use the default delay.
Reloading Changed Assets
So if Turbo Drive replaces the <body>
element of the page and merges the <head>
element, how does it know to reload assets referenced in the <head>
when they change?
To answer that, crack open the app/views/layouts/application.html.erb
file and focus in on the following two lines in the <head>
section:
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
These load the application's bundled CSS stylesheet and JavaScript assets, respectively. And by default, Rails adds a version identifier to these asset URLs. That's typical Rails behavior.
The important part as it relates to Turbo Drive is the addition of "data-turbo-track": "reload"
. This tells Turbo Drive to track the asset URL from one page to the next. And when a tracked asset changes, for example when you deploy a new stylesheet or JavaScript bundle, Turbo Drive will force a full page reload. That way the latest versions of the assets are always being used. 👍
Disabling Turbo Drive
You may encounter situations where you need to disable Turbo Drive for a particular link or form. It's rarely necessary, but worth knowing how to do in a pinch. Simply add a data-turbo
attribute with a value of false
, like so:
<%= link_to "No Turbo", some_path, data: { turbo: false } %>
<%= form_with(url: some_path, data: { turbo: false }) do |f| %>
...
<% end %>
Dive Deeper
For future reference, you may want to bookmark the official Turbo Drive Handbook and Reference.