Last week I added Facebook and Twitter share buttons to my rails app. I thought they were working fine but it seems they were not reliably loaded and required a refresh to get them to show. I thought this was a turbolinks issue as these things often are so I installed the 'jquery-turbolinks'gem. It isn't a turbolinks issue.
After looking around I found answers like this one and whilst adding twttr.widgets.load();
to the end of my twitter function solved that problem, I've had no luck with getting FB.XFBML.parse();
to make the Facebook share button to load without a refresh. On this Facebook dev page it doesn't list the share button as one of the things that can be fixed with that code.
My code, which is in a partial, is as follows:
<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/en_US/sdk.js#xfbml=1&version=v2.0";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk')); FB.XFBML.parse();</script>
<div class="share-buttons">
<div id="fb-root"></div>
<div class="fb-share-button" data-href="#{request.original_url}" data-width="110"></div>
</div>
Last week I added Facebook and Twitter share buttons to my rails app. I thought they were working fine but it seems they were not reliably loaded and required a refresh to get them to show. I thought this was a turbolinks issue as these things often are so I installed the 'jquery-turbolinks'gem. It isn't a turbolinks issue.
After looking around I found answers like this one and whilst adding twttr.widgets.load();
to the end of my twitter function solved that problem, I've had no luck with getting FB.XFBML.parse();
to make the Facebook share button to load without a refresh. On this Facebook dev page it doesn't list the share button as one of the things that can be fixed with that code.
My code, which is in a partial, is as follows:
<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/en_US/sdk.js#xfbml=1&version=v2.0";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk')); FB.XFBML.parse();</script>
<div class="share-buttons">
<div id="fb-root"></div>
<div class="fb-share-button" data-href="#{request.original_url}" data-width="110"></div>
</div>
Share
Improve this question
edited May 23, 2017 at 11:47
CommunityBot
11 silver badge
asked Aug 4, 2014 at 12:39
OssieOssie
1,1132 gold badges13 silver badges32 bronze badges
7
- What do you mean "required a refresh?". If you mean that a browser tab left open from before your deploy didn't update itself automatically after the deploy, then there's no reason why it should (unless you specifically put in some javascript to refresh some or all of the page at regular intervals). – Max Williams Commented Aug 4, 2014 at 12:57
- No, no, I mean the first time you load a page it doesn't have the Facebook share button. If you then click refresh, it does. Across all pages with the link. As reported in the linked answer and for lots of issues with JS find & replace scripts like this. – Ossie Commented Aug 4, 2014 at 13:03
- 1 I have the same issue. Open the page and twitter and fb divs are empty. Refresh the page, and there they are. Lots of supposed solutions that don't change anything. Do I need a piece of js running that just repeatedly fires these off until they load? – JosephK Commented Aug 15, 2014 at 14:24
- 1 Disabling turbolnks in links to the page solved the problem for me. If you have these on many/most pages, best to disable Turbolinks on the entire app. – JosephK Commented Aug 16, 2014 at 4:18
- I guess that's one solution but it seems very destructive especially when the fix for the twitter button worked a treat. I just need a similar javascript tweak for the FB one surely? Unsatisfactory business all round. – Ossie Commented Aug 18, 2014 at 13:55
5 Answers
Reset to default 9 +50It is because sometimes your FB object is not even defined, and your FB.XFBML.parse() function gets called. You need to make calls to FB object when it has initialized. So your code changes to this :
<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/en_US/sdk.js#xfbml=1&version=v2.0";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
window.fbAsyncInit = function(){ // this gets triggered when FB object gets initialized
console.log("FB Object initiated");
FB.XFBML.parse(); // now we can safely call parse method
};
</script>
why not try a client side share button rather then the server side share button. Server side is only needed if you where going to do extra processing after it renders on the server side. Chances are you don't need to render on the server.
<a href="https://www.facebook.com/sharer/sharer.php?u=example.org" target="_blank">
Share on Facebook
</a>
you could also just go to https://developers.facebook.com/docs/plugins/share-button/ pass in the url you would like to share it will generate example code for you. you can then based on that code, change the url of the shared page on the server side using a variable in its place. This would let you have a reusable code snippet that can be used for every page on your site.
<a href="https://www.facebook.com/sharer/sharer.php?u={$pageURLValue}" target="_blank">
Share on Facebook
</a>
When you're rendering the page just set {$pageURLValue} to what the current page is. Sorry i don't know rails so the variable tag may be different. replace {$pageURLValue} with what ever the value tag is for rails.
I was struggeling with the same problem - I had a div popup with an iframe pointing to a html page containing the twitter button. I had the popup hidden from start. This apparently causes the twitter button not to render.. instead of hiding it with display:none / visibility:hidden position the popup far far away (left : -10000px) and reset the left position when you want to show the popup.. Hope it might help someone..
I embedded a Facebook page widget into my website which was an Angular SPA and I had the same "needs a refresh" problem because I had mistakenly put the Script in a parent containing view page called "index.html", but I'd put the embedded DIV in a different sub view specifically on a "social_media.html" page. "index.html" loaded and fired the script on first visit to any page of my website, but at that point had no visibility of the DIV on my as of yet unused and un-requested "social_media.html" view, so when the user eventually navigates to a link that uses the sub view for "social_media.html", "index.html" was not "re-loaded" and thus did not re-fire the script unless I clicked refresh. To fix it I just put the Script and DIVS all into the same "social_media.html" to load and fire at once on all requests for the "social_media.html" to be loaded as a view page. Note: I also had to add DhruvPathak's approach too.
Just call function FB.XFBML.parse();
dynamicaly instead of reloading the page.