A few months ago we decided at Tefter to use Turbolinks with our main Ruby on Rails app, so we can take advantage of its features for better SPA look & feel and faster page loading - at least from the user perspective. Back then we had some Javascript files and we relied heavily on jQuery.
About Tefter
Before going into more detail about the specifics of the migration, let's talk about Tefter first. It's a tool aiming to optimize your web surfing routine, a combination of personal search-engine, a social bookmarking tool, and a place to archive stuff to read later and write notes. One would interact with Tefter through the Web app, the browser extension, the mobile, and the desktop apps or Slack!
Installation
The main repo has a ton of documentation that explains everything. Also, this post from the Hobeybadger team help us a lot at the beginning of the migration.
In our Gemfile
we added:
gem 'turbolinks'
And installed it with Yarn:
yarn add turbolinks
Then in our packs/application.js
file we import and start Turbolinks:
import Turbolinks from "turbolinks"
Turbolinks.start()
Migration
The steps we did for migration to work were the following:
- We changed all
document.ready
withturbolinks:load
events.
// Old
$(document).ready(function() { ...
// New
$(document).on('turbolinks:load', function() { ...
And all
DOMContentLoaded
events withturbolinks:load
We moved all logic from
window.onload
events toturbolinks:load
We did the same with
window.resize
events.We made sure to clear Turbolinks cache before ajax requests
// Clear Turbolinks cache before ajax requests
document.addEventListener('ajax:before [data-remote]', () => {
Turbolinks.clearCache();
});
We disabled Turbolinks for Facebook, Google, Slack, and Github omni-oauth sign up pages.
We disabled Turbolinks from other 3rd parties calls like Pocket authorization and Slack installation.
We noticed that we had problems with rendering some Javascript components like modals or tooltips (we use for example Micromodal and tippy). For those cases, we explicitly opted out from Turbolinks:
<div class="modal" data-turbolinks="false">
or
<%= link_to '#', class: 'tippy', data: { turbolinks: false } do %>
We experienced some rendering issues with views with different layouts. We should investigate these issues further but because there was only a simple case (our Readable view) we decided to opt out Turbolinks from it.
We had some hard times dealing with event listeners loaded inside
turbolinks:load
functions. We ended up using Stimulus and handle them insideconnect()
functionsIn one case we wanted to make an ajax call and we discovered that we should add the security token.
$.ajax({
url: someUrl,
method: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content'))
},
- We found some inconsistencies when we use
turbolinks:onload
and async javascript loading. We switched todefer
.
Feelings
We have a small JavaScript codebase but the overall migration and bug fixing took us some time mainly due to our inexperiences with the Turbolinks architecture and its expectations. Overall the sign is positive. If you have an existing codebase be patient, there will be plenty of small bugs. Fortunately, one should get quickly familiar with solving them.
Top comments (0)