RSS
 

Dynamic Facebook and Tweetmeme Widgets

09 Apr

We just made a change on YouTube videos so that at the end of playback a Facebook “share” button and a Tweetmeme “retweet” button appear as part of an effort to encourage users to spread videos in their personal social networks.


This presented a couple of problems because, similar to an issue touched on in my last clog, the widgets needed to be inserted dynamically and that’s usually easier said than done. After a little bit of digging into how the widgets function, I was able to make them seemingly load normally on-the-fly.

Dynamic Facebook Share Button

Facebook share buttons are created in a couple of pieces. I started with the default widget code supplied by Facebook:

<a type="button_count" name="fb_share"
  href="http://www.facebook.com/sharer.php">Share</a>
<script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>

Understanding how to make this work dynamically first means understanding what exactly this code does. The <a> tag is clearly a link to Facebook’s share service where users can submit our page. The <script> tag loads a JavaScript object named FB.Share.

Failed Insertion

If you were to try inserting these bits of code dynamically, you’d discover in no time flat that it just won’t work. For example, this might look like a good idea, but it’s useless:

$("#somediv").append('<a type="button_count" name="fb_share" '+
  'href="http://www.facebook.com/sharer.php">Share</a>');
$("#somediv").append('<script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" '+
  'type="text/javascript"></script>');

And you may even try it a little more manually by directly modifying the DOM:

a = document.createElement('a');
a.type='button_count';
a.name='fb_share';
a.href='http://www.facebook.com/sharer.php';
a.innerHTML = 'Share';
document.getElementById('somediv').appendChild(a);

s = document.createElement('script');
s.type='text/javascript';
s.src='http://static.ak.fbcdn.net/connect.php/js/FB.Share';
document.getElementById('somediv').appendChild(s);

But you’ll be disappointed by the results. A working solution required a little more digging.

Successful Buttonization

I opened Facebook’s JavaScript file and started sniffing around. Their code is designed to initialize all buttons on the page just once, which makes perfect sense. So the solution is to add the <a> tag as per the above but then manually force FB.Share to re-execute, thus turning our dynamically added link into a button. The required function call is rather simple:

if (typeof(FB.Share) != 'undefined') {// make sure it exists
  // FB.Share.onFirst();
  // *** UPDATE: 17 Aug 2011 - Thanks to zr0ck who informed
  // FB has modified their Share script ***
  // FB.Share.onFirst() no longer exists; you must now instead call:
  FB.Share.renderPass();
}

Just execute that after you’ve inserted your <a> link and it’ll become a pretty Facebook button.

Multiple Buttons Per Page

The above solution works splendidly, assuming that you use it on a URL specific to the content you’re sharing because FB.Share will by default use the address of the current page when adding to the user’s wall. However, if you are on a listing page where there are multiple content posts and the URL is not specific to any one of them (e.g., http://videosift.com), then every dynamic button you add will reference the same address.

Facebook provides a straightforward method for you to specify an alternate URL than the current one, which is to add a u variable to the query string of the link:

<a type="button_count" name="fb_share"
  href="http://www.facebook.com/sharer.php?u=SOMEURL">

However that method doesn’t work with our dynamic buttonizing for whatever reason. A little more sniffing through the FB.Share code reveals exactly how it determines what URL to use:

FB.Share {
//...
getUrl:function(a){return a.getAttribute('share_url')||window.location.href;}
//...
}

Aha- it checks for an attribute named share_url. So all we have to do is add that attribute to our link et voila, we’re in business!

<a type="button_count" name="fb_share"
  href="http://www.facebook.com/sharer.php" share_url="SOMEURL">

Dynamic Tweetmeme Retweet Button

Fortunately, the retweet button was much less involved than the FB share button, but also require just a little bit of digging. As described on tweetmeme’s widget page, the following is the code you’d typically want to use on a web page:

<script type="text/javascript">
tweetmeme_url = 'http://yoururl.com';
</script>
<script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>

As with the FB widget, attempting to insert this code into the DOM on-the-fly just results in failure. (I’ll spare you the sample broken code.) So I cracked open the button’s js code and investigated how it worked.

It turns out tweetmeme doesn’t use a lot of JS tomfoolery to make their widgets work. Instead, they insert a simple <iframe> and allow that to do all work, which makes it easy for us because all we have to do is insert the same type of iframe and we’re in business. So we did something like the following and it worked like a charm:

$("#somediv").append('<iframe frameborder="0" scrolling="no" height="61" width="50"
  src="http://api.tweetmeme.com/button.js?url='+SOMEURL+'"></iframe>');

Enjoy!

 

220,065 views

Tags: , , , , , , ,

Leave a Reply

 

 
  1. Anonymous

    June 20, 2010 at 3:59 am

    Smart info and I just like the layout and theme of your site too. I hope this website keeps growing and you still build it.

     
  2. Devin Walker

    July 15, 2010 at 8:44 am

    Great post and nice looking blog. I’ve added the dynamic facebook code and a bunch to my NextGen Gallery! Awesome!!

     
  3. Eunil

    October 12, 2010 at 2:57 pm

    Thanks for the codes. I have used them on my personal site and I hope to get more from here.

     
  4. Rachal

    October 25, 2010 at 10:37 pm

    Dude..I love you Dude..

     
  5. Mike

    July 12, 2011 at 9:06 am

    I was unable to get the Twitter to work dynamically. What did the final code end up looking like? Thank you in advanced and good clog here : )

     
  6. rommel

    July 12, 2011 at 9:19 am

    Mike- That last bit of javascript is all you need to insert a Tweetmeme widget dynamically, assuming you’re using jQuery.

    Just replace “#somediv” with your own selector or page element and SOMEURL with the URL with which you’d like the button to be associated.

     
  7. zr0ck

    August 16, 2011 at 11:05 pm

    Hi, I’d like to update this. For facebook you actually need to call:

    FB.Share.renderPass();

    onFirst doesnt seem to work anymore

     
  8. ekrem

    December 28, 2011 at 8:14 am

    FB.Share {
    //…
    getUrl:function(a){return a.getAttribute(‘share_url’)||window.location.href;}
    //…
    }

    I don’t know how to use this , Can you help me please?

     
  9. rommel

    December 28, 2011 at 8:34 am

    @ekrem: The bottom line with that is you just need to specify a “share_url” attribute set to the URL you’d like shared. See the example snippet above. (It’s just below the code you copied from the post.)

     
  10. ekrem

    December 28, 2011 at 9:19 am

    Thanks a lot @rommel .I have seen share_url , but If I use
    FB.Share {
    //…
    getUrl:function(a){return a.getAttribute(’share_url’)||window.location.href;}
    //…
    } the share button can’t be seen

     
  11. rommel

    December 28, 2011 at 9:22 am

    @ekrem: You don’t use the code yourself that you’re pasting. That came from the Facebook Share initialization script and was included to illustrate why adding the share_url attribute works.

     
  12. ekrem

    December 28, 2011 at 9:46 am

    Thanks a lot @rommel

     
  13. ekrem

    January 13, 2012 at 6:38 pm

    I am in trouble.Can anyone help me? Is there any way to change the share_url like a.share_url=encodeURIComponent(window.location)

     
  14. ekrem

    January 14, 2012 at 10:06 am

    Someone can help me please.I need to share my own url but this code doesnt work for me

     
  15. rommel

    January 14, 2012 at 10:38 am

    It seems that FB has changed even more the way they do their button initialization. If that’s the case, I can’t say for sure in detail how to correct your issue. At the very least, try the method using the static share_url attribute.