[Rails, Hotwire] Migrate to Turbo from rails-ujs and turbolinks – how it went for us.
We recently decided to migrate one of our newest platforms to Turbo. The goal of this article is to help anyone who plans to do the same migration. I hope it gives you a perspective of the amount of work required. Generally it was easy and straightforward, but a few specs had to be changed because of urls and controller results
Gemfile
Remove turbolinks and add turbo-rails. The change was
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -227,9 +227,8 @@ GEM
switch_user (1.5.4)
thor (1.1.0)
tilt (2.0.10)
- turbolinks (5.2.1)
- turbolinks-source (~> 5.2)
- turbolinks-source (5.2.0)
+ turbo-rails (0.7.8)
+ rails (>= 6.0.0)
application.js and no more rails-ujs and Turbolinks
Added “@notwired/turbo-rails” and removed Rails.start() and Turbolinks.start()
--- a/app/javascript/packs/application.js
+++ b/app/javascript/packs/application.js
@@ -3,8 +3,7 @@
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
-import Rails from "@rails/ujs"
-import Turbolinks from "turbolinks"
+import "@hotwired/turbo-rails"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
@@ -14,8 +13,6 @@ import "channels"
// Collapse - needed for navbar
import { Collapse } from 'bootstrap';
-Rails.start()
-Turbolinks.start()
ActiveStorage.start()
package.json
The change was small
--- a/package.json
+++ b/package.json
@@ -2,10 +2,10 @@
"name": "platform",
"private": true,
"dependencies": {
+ "@hotwired/turbo-rails": "^7.0.0-rc.3",
"@popperjs/core": "^2.9.2",
"@rails/actioncable": "^6.0.0",
"@rails/activestorage": "^6.0.0",
- "@rails/ujs": "^6.0.0",
"@rails/webpacker": "5.4.0",
"bootstrap": "^5.0.2",
"stimulus": "^2.0.0",
Device still does not work
For the device forms you have to add “data: {turbo: ‘false’}” to disable turbo for them
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }, data: {turbo: "false"}) do |f| %>;
We are waiting for resolutions on https://github.com/heartcombo/devise/pull/5340
Controllers have to return an unprocessable_entity on form errors
If there are active_record.errors in the controller we must now return status: :unprocessable_entity
+++ b/app/controllers/records_controller.rb
@@ -14,7 +14,7 @@ class RecordsController < ApplicationController
if @record.save
redirect_to edit_record_path(@record)
else
- render :new
+ render :new, status: :unprocessable_entity
end
end
application.js was reduced significantly
The old application.js – 923 KiB
application (932 KiB)
js/application-dce2ae8c3797246e3c4b.js
The new application.js – 248 KiB
remote: Assets:
remote: js/application-b52f4ecd1b3d48f2f393.js (248 KiB)
Conclusion
Overall a good experience. We are still facing some minor issues with third party chat widgets like tawk.to that do not work well with turbo, as they are sending 1 more request, refreshing the page and adding the widget to an iframe that is lost with turbo navigation. But we would probably move away from tawk.to.
Reply
You must be logged in to post a comment.