I’ve run into this a couple of times lately. Everything works fine when refreshing a page, but when navigating there via turbolinks the JS doesn’t work.

Here’s how I’m handling it.


Turbolinks likes to have any JavaScript in the head tag so I add a yield tag to the head in the layout.

  = yield :js_head


Then in the view I use content_for to grab the JS and drop it in the header.

= content_for :js_head do
  script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js" type="text/javascript" data-turbolinks-track="reload"

    function loadChart() {
      var ctx = document.getElementById('activityChart').getContext('2d');
      var chart = new Chart(ctx, {
        // The type of chart we want to create
        type: 'line',

        // The data for our dataset
        data: {
          labels: #{raw @activity.map{|x| x[0].strftime("%b %d")}.to_json},
            datasets: [{
              label: "Searches",
                borderColor: 'rgb(0, 132, 255)',
                data: #{raw @activity.map{|x| x[2]}.to_json},
              label: "Clicks",
                borderColor: 'rgb(255, 99, 132)',
                data: #{raw @activity.map{|x| x[1]}.to_json},

        // Configuration options go here
        options: {}

    function unloadChart() {
      document.removeEventListener('turbolinks:load', loadChart);
      document.removeEventListener('turbolinks:click', unloadChart);

    document.addEventListener('turbolinks:load', loadChart);
    document.addEventListener('turbolinks:click', unloadChart);

Seems like in addition to the placement, I need to hook into the turbolinks:load event and turbolinks:click event.

The load event fires the code on page load, both when refreshing and when navigating there with a link.

The click event is used to unbind the events so they don’t continue to fire on other pages.

Seems like a common issue that would come up a lot, but maybe not.