Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook share button not loading with Rails turbolinks

I was following Facebook general guidlines to include Share button (Social Plugin) https://developers.facebook.com/docs/plugins/share-button

_social.html.erb

<div id="fb-root"><div class="fb-share-button" data-href="http://www.example.com" data-layout="button_count"></div></div>

fb_share.js

var fb_share;
fb_share = function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.3&appId=xxxxxxxxxxxxxxx";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk');

$(document).ready(fb_share);
$(document).on('page:load', fb_share)

application.js

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require_tree .

The button renders on first page load, works correctly also. But is not rendered when navigating to next page and back.

If I include fb_share.js file in application.js file (before turbolinks) it doesn't show up at all.

like image 543
MartinsB Avatar asked May 15 '15 10:05

MartinsB


3 Answers

For Turbolinks 5, this is the only thing that worked for me: https://gist.github.com/6temes/52648dc6b3adbbf05da3942794b97a00

// FacebookSDK
// https://developers.facebook.com/docs/plugins/page-plugin/
(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s);
  js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk')); // Replace 'facebook-jssdk' with your page id.

// Compatibility with Turbolinks 5
(function($) {
  var fbRoot;

  function saveFacebookRoot() {
    if ($('#fb-root').length) {
      fbRoot = $('#fb-root').detach();
    }
  };

  function restoreFacebookRoot() {
    if (fbRoot != null) {
      if ($('#fb-root').length) {
        $('#fb-root').replaceWith(fbRoot);
      } else {
        $('body').append(fbRoot);
      }
    }

    if (typeof FB !== "undefined" && FB !== null) { // Instance of FacebookSDK
      FB.XFBML.parse();
    }
  };

  document.addEventListener('turbolinks:request-start', saveFacebookRoot)
  document.addEventListener('turbolinks:load', restoreFacebookRoot)
}(jQuery));
like image 120
Arel Avatar answered Nov 03 '22 09:11

Arel


The Facebook JS SDK only goes through the HTML document once upon initialization, to look for elements to replace with the FB social plugins.

And trying to embed the JS SDK again, as you are trying by calling fb_share, is useless – because that code is specifically written to not embed it again, if it has been embedded already.

The correct way to get the SDK to parse the document again for content added only later on, is to call FB.XFBML.parse.

like image 45
CBroe Avatar answered Nov 03 '22 07:11

CBroe


For TurboLinks 5 this worked for me!

It is necessary to add data-turbolinks-permanent to the fb-root element!

<div id="fb-root" data-turbolinks-permanent></div>
<script>
(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/de_DE/sdk.js#xfbml=1&version=v2.9";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

document.addEventListener("turbolinks:load", function() {
  if(window.FB) {
    FB.XFBML.parse();
  }
});
</script>
like image 2
Betty St Avatar answered Nov 03 '22 09:11

Betty St