Bits for hackers.

Making Turbolinks and Jquery Co-exist in a Rails App

What are turbolinks

Turbolinks is a feature that was introduced with Rails 4 (but work with Rails 3 as well) , which greatly increases the speed and performance of a Rails App. Turbolinks allows an application to load new pages at high speeds by using Javascript to call the title (in the head of your html) and body of your app every time you click on a link - it doesn’t actually query for the entire html document over and over again every time you click a link. If you’ve ever worked with AJAX before, Turbolinks works in a very similar way where it makes a call to your server to load up the content that you requested. Therefore, you don’t technically get a full page refresh when you work with turbolinks even though it looks like you do.

Issues can arise when using JQuery and turbolinks…

If you have a Rails app that utilizes a lot of JQuery, you may start to notice that some that you’re using JQuery with don’t work as they should when you click between links of pages. This is because traditionally, a lot of JQuery requires some function to fire off after receiving the document ready event:

1
2
3
$(document).ready(function(){
  // all your jquery goes here after the document ready event is fired off
})

Because turbolinks don’t technically refresh the page every time you click on a link, the document ready event will never fire off and therefore never run any of the code within you document ready. If you’re not sure whether your app has these symptoms or not, try refreshing the page yourself and seeing if the page now works as it should - if it does, you can be sure that it is a turbolinks issue.

So how can you fix this?

There are a number of ways to do this. My favorite method is to use the JQuery Turbolinks gem. With this gem, all you have to do is:

  1. Add it to your gemfile with `gem ‘jquery-turbolinks’`
  2. Add it to your javascript manifest file in the specified order below:
    1
    2
    3
    4
    5
    6
    7
    
    //= require jquery
    //= require jquery.turbolinks
    //= require jquery_ujs
    //
    // ... your other scripts here ...
    //
    //= require turbolinks
    

Another method to fix this issue is to not bind to the page load event but rather to bind to other events on the document such as page:load. Other events that you can bind to as well (depending on what you are trying to do) include:

  • page:before-change
  • page:fetch
  • page:receive
  • page:before-unload
  • page:change
  • page:update

Using either of these methods should fix all of your turbolinks and JQuery issues while still allowing you to take advantage of the speed that turbolinks provides.