Turbolinks prevents normal $(document).ready()
events from firing on all page visits besides the initial load, as discussed here and here. None of the solutions in the linked answers work with Rails 5, though. How can I run code on each page visit like in prior versions?
9 Answers
Rather than listen to the ready
event, you need to hook in to an event fired by Turbolinks for every page visit.
Unfortunately, Turbolinks 5 (which is the version that appears in Rails 5) has been re-written, and does not use the same event names as in previous versions of Turbolinks, causing the answers mentioned to fail. What works now is to listen to the turbolinks:load event like so:
$( document ).on('turbolinks:load', function() {
console.log("It works on each visit!")
})

- 3,418
- 2
- 15
- 27
-
6Yes. Explained here as well. http://guides.rubyonrails.org/working_with_javascript_in_rails.html#turbolinks. Check 5.2 Page Change Events. – Indika K Jul 10 '16 at 06:58
-
3turbolinks:load fires for me locally, but not on Heroku. I see my custom javascript code in my compiled js assets, but the event isn't firing. – psparrow Sep 22 '16 at 16:03
-
this not work well. I have a select2 and when change the page and back I have two select2 (duplicated) – inye Oct 18 '16 at 17:00
-
Yes that's true @inye I have the same issue and I also have opened a issue at [GitHub](https://github.com/mkhairi/materialize-sass/issues/130). Have you solved somehow? – alexventuraio Dec 16 '16 at 06:55
-
3Despite what the Rail doc says, I'm using `on('ready turbolinks:load')` otherwise I have some problems on some pages – Cyril Duchon-Doris Dec 22 '16 at 11:31
-
1Hi Cyril, I am having the same problem, i.e. need to trigger on initial page load as well as turbolinks:load. I have asked a question about this on SO, http://stackoverflow.com/questions/41421496/turbolinks-load-event-not-working-on-with-page-refresh. Do you have any more insight as to why this is so? Are you using jquery-turbolinks (I am). The only good thing is it makes sure your code is idempotent. – Obromios Jan 06 '17 at 06:23
-
For me, `$(document).on('turbolinks:load', ...)` did _not_ work; I had to use `document.addEventListener('turbolinks:load', ...` as described in the [Turbolinks README](https://github.com/turbolinks/turbolinks/blob/master/README.md#running-javascript-when-a-page-loads). – bovender Jan 31 '17 at 05:07
-
@bovender That worked but I'm using a jquery upload button and file field with a progress bar. It adds another progress bar every time the page loads. – Beartech Apr 04 '17 at 18:54
-
and could be used as following: ```$(document).on 'ready, turbolinks:load', ->``` ? – user1136228 Sep 26 '17 at 18:41
-
@CyrilDuchon-Doris That only makes it fire twice, hence why it isn't mentioned in the doc. As github.com/turbolinks/turbolinks/#observing-navigation-events says, you should do it like this: `$(document).ready(function() { $(document).on('turbolinks:load', function() {} ) })` – ckhatton Nov 21 '19 at 13:32
-
2Is this different for rails 6? – stevec Sep 26 '20 at 12:45
Native JS :
document.addEventListener("turbolinks:load", function() {
console.log('It works on each visit!');
});
In rails 5 the easiest solution is to use:
$(document).on('ready turbolinks:load', function() {});
Instead of $(document).ready
. Works like a charm.

- 2,243
- 3
- 26
- 47
-
12Don't add `ready` to the list, otherwise the function will be executed twice. As https://github.com/turbolinks/turbolinks/#observing-navigation-events said, you should do it like this: ```javascript $(document).ready(function() { $(document).on('turbolinks:load', function() {} ) }) ``` – Xiaohui Zhang Dec 30 '18 at 08:43
-
@XiaohuiZhang Are you sure that's gonna work???? Because if `$(document).ready` gets triggered, then at least in my own scenarios, I wouldn't need `turbolinks:load` – Milad.Nozari Dec 31 '18 at 06:20
-
@XiaohuiZhang If your script has to work on a page with turbolinks and on a page without, that will not work on the page without, because it will need the turbolinks:load event to execute the code – cercxtrova Sep 05 '19 at 09:31
-
@escanxr It works both, you can try it out. because Turbolinks always trigger "turbolinks:load" event whenever a Turbolinks page or not. – Xiaohui Zhang Sep 06 '19 at 17:45
-
2@XiaohuiZhang I tried with Turbolinks 5, it didn't work. If turbolinks is disabled on the page, only `ready` event is triggered. If there's turbolinks, the code is called twice – cercxtrova Sep 07 '19 at 22:22
This is my solution, override jQuery.fn.ready
, then $(document).ready
works without any change:
jQuery.fn.ready = (fn)->
$(this).on 'turbolinks:load', fn

- 985
- 8
- 12
-
This is exactly what I needed. This works for external libraries that rely on `document` callbacks as well. Why the downvote? This should be safe as long as turbolinks is used throughout the entire application, right? – Dylan Vander Berg Jun 12 '17 at 15:48
(For coffeescript)
I Use:
$(document).on 'turbolinks:load', ->
Instead of:
$(document).on('turbolinks:load', function() {...})

- 81
- 7
-
I have done that and I still getting this issue as @inye said : https://github.com/mkhairi/materialize-sass/issues/130. Using JS or Coffee does not really make any difference, at least NOT for me. – alexventuraio Dec 16 '16 at 07:22
-
2
-
My guess is that this is coffeescript and not native javascript? I gave it a +1 because this is exactly what I'm doing and it works for me (in my coffeescript file) – aarona May 28 '19 at 16:07
-
pure modern js:
const onLoad = () => {
alert("works")
}
document.addEventListener("load", onLoad)
document.addEventListener("turbolinks:load", onLoad)
with turbo it's turbo:load

- 7,749
- 4
- 38
- 57
Here is solution that work for me, from here:
install
gem 'jquery-turbolinks'
add this .coffee file to your app: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee
name it turbolinks-compatibility.coffee
at application.js
//= require jquery //= require jquery_ujs //= require jquery.turbolinks //= require turbolinks //= require turbolinks-compatibility

- 3,777
- 1
- 36
- 46
-
What about in `production` env? Have you tested it out? There are some people telling it just work fine in `development` mode. – alexventuraio Dec 16 '16 at 07:08
-
6
While we await the fix to this really cool gem, I was able to move forward by modifying the following;
addCallback: (callback) ->
if $.turbo.isReady
callback($)
$document.on 'turbo:ready', -> callback($)
to:
addCallback: (callback) ->
if $.turbo.isReady
callback($)
$document.on 'turbolinks:load', -> callback($)
I'm not yet aware what this does not resolve, but it seemed to work well on initial inspection.

- 11
- 1
Use the light-weight gem jquery-turbolinks.
It makes $(document).ready()
work with Turbolinks without changing existing code.
Alternatively, you could change $(document).ready()
to one of:
$(document).on('page:fetch', function() { /* your code here */ });
$(document).on('page:change', function() { /* your code here */ });
depending on which one is more appropriate in your situation.

- 1,916
- 2
- 19
- 39
-
jquery-turbolinks doesn't yet support Turbolinks 5 https://github.com/kossnocorp/jquery.turbolinks/issues/56 – AndrewH Jun 27 '16 at 17:17
-
-
2