Diagnosing Turbo Drive full page reloads in Rails
When Turbo Drive falls back to full page reloads, links and forms behave like traditional HTTP navigation. This guide shows how to find the cause and restore partial-page updates.
16 Nov 2025, 19:30 UTC

The problem and what to check first
You click a link or submit a form in a Rails application using Hotwire, and the browser performs a full document reload: the screen flickers, the address bar changes, and client-side state such as scroll position or open dropdowns is lost. Turbo Drive is the Hotwire library that intercepts these clicks and submissions so the page can update without a hard navigation. When it falls back, Turbo is either not loaded, explicitly disabled for that element, or blocked by the browser before it can run.
Useful takeaway: confirm Turbo is present and active in the browser before changing server code or controller responses.
Common causes and diagnostic table
| Recognizable condition | Likely cause | Where to look |
|---|---|---|
| Link click causes a full page reload | data-turbo="false" on the link, <body>, or <meta name="turbo-visit-control" content="reload"> | HTML source and DevTools Elements panel |
| Form submission reloads the page | jQuery UJS remote: true conflicting with Turbo Drive, or data-turbo="false" on the form | Form markup and Gemfile for jquery-ujs |
window.Turbo is undefined in console | turbo-rails gem missing or JavaScript bundle not importing Turbo | Gemfile, application.js, or importmap config |
| Works locally but not in production | Content Security Policy blocking turbo.js or inline Turbo initialization | DevTools Console and Network panel for CSP violations |
| Turbo Frame navigation reloads the whole page | Missing or mismatched id on <turbo-frame>, or response lacks a matching frame | Frame markup and controller response HTML |
Ordered checks
- Confirm Turbo is installed. Run in the Rails application root:
Expected: a line such ascd bundle list | grep turboturbo-rails (x.x.x). Permissions: read access to application files. Risk: none. - Confirm Turbo reaches the browser. Open DevTools Console on any application page and run:
Expected: an object, notconsole.log(window.Turbo)undefined. Permissions: none. Risk: none. - Test whether Turbo is intercepting navigation. Paste this temporary listener in DevTools Console, then click a suspect link:
Expected: a console message on each link click. If nothing logs, Turbo Drive is not intercepting that navigation. Remove the listener after testing.document.addEventListener('turbo:before-visit', (event) => { console.log('Turbo intercepted:', event.data.url); }); - Audit disabling attributes. Run at the application root:
Expected: no matches on links, forms, orgrep -R 'data-turbo="false"' app/views config grep -R 'turbo-visit-control' app/views config<body>that should use Turbo. Permissions: read access. Risk: none. - Check Content Security Policy. Open DevTools Console and Network, then navigate. Expected: no CSP errors blocking
turbo.jsor inline scripts. If errors appear, note the blocked directive.
Fixes tied to findings
- Remove
data-turbo="false"from links, forms, or<body>when those elements should use Turbo Drive. Scope it only to elements that genuinely need hard navigation. - Remove or change
<meta name="turbo-visit-control" content="reload">if you want Turbo to cache and reuse visits. This meta tag forces a full reload on return visits. - Install Turbo if missing. Add to Gemfile:
Then rungem "turbo-rails"bundle installat the application root (write permissions to Gemfile and Gemfile.lock), restart the application server, and reload the page. Risk: dependency changes can affect other gems; verify in staging first. - Ensure Turbo is imported. With importmap, confirm
config/importmap.rbpins Turbo; with a bundler-based frontend, confirmapplication.jsimports@hotwired/turbo-rails. Reload the application after changes. - Resolve jQuery UJS conflicts. Remove
remote: truefrom forms handled by Turbo Drive, or migrate those forms to Turbo Frames. Do not run both UJS Ajax and Turbo Drive on the same submission. - Fix CSP for Turbo assets. Add the Turbo script origin to the
script-srcdirective, or configure nonces, rather than disabling CSP. Test the policy in staging before production. - Match Turbo Frame identifiers. Ensure the
<turbo-frame id="...">on the page has the sameidas the frame in the response HTML, and review framesrcandtargetorigins in multi-domain deployments to avoid loading unintended cross-origin content.
Escalation criteria
- Escalate to the frontend or Hotwire maintainer if
window.Turboremains undefined after installingturbo-railsand reloading the JavaScript bundle. - Escalate to infrastructure if Turbo events fire but the browser still performs hard reloads across multiple browsers, or if a proxy strips Turbo-related responses in production but not locally.
- Routine removal of
data-turbo="false"or CSP adjustments are team-level configuration changes and do not require escalation.
Limitations
- This guide covers Turbo Drive navigation in Rails 7.0+ with
turbo-rails. It does not cover Turbo Streams broadcasts or Turbo Native WebView containers. - Turbo Drive updates the page from HTML responses; it does not automatically partial-update a page unless a Turbo Frame or Turbo Stream is involved.
- Behavior in Turbo Native mobile wrappers differs from browser behavior and is outside this guide.
Practical way to check the result
After applying a fix, reload the application, open DevTools Console, run the turbo:before-visit listener from check 3, and click the previously broken link. A logged message plus no full-page flicker indicates Turbo Drive is intercepting navigation. In the Network tab, confirm the navigation completes as a single fetch rather than a hard document reload.
Rollback
Only bundle add, Gemfile edits, and JavaScript import changes alter application state. To revert them:
git checkout -- Gemfile Gemfile.lock app/javascript/application.js config/importmap.rb
bundle install
Then restart the application server and confirm window.Turbo returns to its previous state. If you did not modify files, there is nothing to roll back.