Social Buttons: Adding them to your site & Tracking them

I’ve had a lot of questions recently (like literally, several a day) on how I implemented the social buttons in WordPress, whether I was using a plugin or using a theme. First of all I’m glad to see all of you noticing my social buttons section so much. Second, I’d love to share with you how I built this, because I actually made it load nice and fast too and would love for you to have that.

In full “shape” my social buttons look like this:

social buttons in WordPress

There are several plugins that do social buttons in WordPress. As a lot of you may know, I used to maintain a plugin called Sociable back in the day when social buttons where all still 16×16, simple, buttons. At some point, I think it was Digg that introduced the script based social button with a counter in it, which was later on adopted by several social sites. To date, there are many many social bookmarking sites that have widgets like these. Not every site needs all of these social buttons. I picked the 5 that work for me, your mileage may vary.

How did you implement these social buttons in WordPress?

I hear you thinking “get on with it already”. Ok ok ok. Here we go. It’s not a plugin. It’s in my theme. Which doesn’t mean it couldn’t be a plugin, it’s just that it’d be pretty hard to embed them in my site as sweet as these social buttons are embedded right now, using a plugin.

So they’re in my theme. As you can guess, the buttons themselves are a template part. This template part is actually rather small and simple, it looks like this (line breaks added for readability):

<ul class="social buttons">
    <fb:like href="<?php the_permalink() ?>" send="true"
      showfaces="false" width="120" layout="button_count"
    <a href="" data-url="<?php the_permalink(); ?>"
      data-text="< ?php the_title(); ?>" data-via="example"
    <g:plusone size="medium" callback="plusone_vote"></g:plusone>
    <script type="in/share" data-url="<?php the_permalink(); ?>"
    <div id="stumbleupon-button"></div>

As you can see, these are the “regular” buttons for most of these services, with that exception that all of them are lacking the script tag. Back in february, Frederick did an awesome post on his blog about optimizing the performance of widgets & buttons. I used the knowledge in this post, but took it a few steps further.

Loading these Social Buttons script files

Let’s start with Facebook. Their asynchronous code works quite well. First, make sure you have a fb-root div:

<div id="fb-root"></div>

Then load the JavaScript, (all of the code samples below should be within <script> tags):

window.fbAsyncInit = function() {
  FB.init({appId: '<APPID>', status: true, cookie: true, xfbml: true});
(function() {
  var e = document.createElement('script');
  e.type = 'text/javascript';
  e.src = document.location.protocol +
  e.async = true;

This loads the Facebook JS once the page load is done, which works quite nice and then loads the app. Later on we’ll be adding code to track all the interaction with the Facebook buttons, but let’s load some other social buttons first.

The other scripts I’m going to load using jQuery. Not only do I load them asynchronously, I only start loading them when the page has actually already completed rendering. The code to do that for the Twitter share button looks like this:

jQuery(document).ready(function($) {
  // Load Tweet Button Script
  var e = document.createElement('script');
  e.type="text/javascript"; e.async = true;
  e.src = '';

And LinkedIn, Google’s +1 and StumbleUpon’s buttons work in the same way:

jQuery(document).ready(function($) {
  // Load LinkedIn button
  var e = document.createElement('script');
  e.type="text/javascript"; e.async = true;
  e.src = '';
  // Load Plus One Button
  var e = document.createElement('script');
  e.type="text/javascript"; e.async = true;
  e.src = '';
  // Load StumbleUpon button
  var e = document.createElement('script');
  e.type="text/javascript"; e.async = true;
  e.src =

You could even simplify this further by just making it an array and looping through it, but for readability’s sake I didn’t do that.

Tracking Interaction with Social Buttons

When Google released +1, I quickly identified how to track interaction with that button. The obvious “follow up” was questions from people on how to track interaction with other buttons. Not for each of these social buttons tracking of interaction is actually possible. It depends on how the button was designed whether this will work or not. I got it working for Twitter and Facebook, so I’ll share the code for tracking interaction with their respective social buttons below.

For Facebook, it’s pretty well documented around the web how you can track the interaction with their buttons. I played around a bit and came up with the following implementation, which tracks the interaction with my like & send buttons and with the big like box on the right. It tracks the interaction in both Google Analytics and getClicky.

Instead of just the above FB.init line, we’ll do the following:

window.fbAsyncInit = function() {
  FB.init({appId: '<APPID>', status: true, cookie: true, xfbml: true});
  FB.Event.subscribe("edge.create",function(response) {
    if (response.indexOf("") > 0) {
      // if the returned link contains 'facebook,com'. It is a 'Like'
      // for your Facebook page
      clicky.log(response,'Facebook Like Facebook Page');
    } else {
      // else, somebody is sharing the current page on their wall
      clicky.log(response,'Facebook Like / Share Post');
    clicky.log(response,'Facebook Send Post');

As you can see, if you can read a bit of code, this will create different events for each of the different optional actions. Now, let’s do the same for the Tweet button (using examples based on their docs, but switched to async):

// Load Tweet Button Script & Associate Google Analytics Tracking
var e = document.createElement('script');
e.type="text/javascript"; e.async = true;
e.src = '';
$(e).load(function() {
  function tweetIntentToAnalytics(intent_event) {
    if (intent_event) {
      var label =;
      _gaq.push(['_trackEvent', 'twitter_web_intents',
	    intent_event.type, label]);
      clicky.log(document.location.href,'Twitter '+label);
  function followIntentToAnalytics(intent_event) {
    if (intent_event) {
      var label = + " (" + + ")";
      _gaq.push(['_trackEvent', 'twitter_web_intents',
	   intent_event.type, label]);
      clicky.log(document.location.href,'Twitter '+label);
  }'tweet',    tweetIntentToAnalytics);'follow',   followIntentToAnalytics);

LinkedIn has an API for these things, at least, it has documentation for it, but it doesn’t work in my testing and quite a few people are complaining on LinkedIn’s developer forums as well. For StumbleUpon there’s no documentation to be found and it doesn’t seem to be possible at this time to track interaction with their social button.

All of this is pretty geeky, I know, but there’s a lot of value in both implementing these social buttons in a good and fast way and measuring all these interactions. Seeing which sort of social buttons work for which types of traffic can really help you find what you should be optimizing how.

Tags: , , , , runs on the Genesis Framework

Genesis theme frameworkThe Genesis Framework empowers you to quickly and easily build incredible websites with WordPress. Whether you're a novice or advanced developer, Genesis provides you with the secure and search-engine-optimized foundation that takes WordPress to places you never thought it could go.

Read our Genesis review or get Genesis now!

58 Responses

  1. D. SchmitzBy D. Schmitz on 23 June, 2011

    I like your Plugin and yout tutorials.
    Do you know Piwi?
    A open source real time web analytics software program. I use it on our site and I like it :-)
    Maybe you can write the same tut. for both google and piwi ?

    ps. sorry for my bad english.

    • Joost de ValkBy Joost de Valk on 25 June, 2011

      I know Piwik but it’s been quite a while since i looked at it, so no I can’t really write that tutorial :)

      • D. SchmitzBy D. Schmitz on 25 June, 2011

        The project is developing really fast and the inclusion in the WP is very well done, even the live tracking is brilliant.
        Maybe you can even imagine once when your plugin reviews.
        And no, I do not work there. I use it only.

        ps. Thanks for fix the comment Problem.

  2. sandeepBy sandeep on 23 June, 2011

    nice one , thanks!

  3. eric bBy eric b on 24 June, 2011

    I like to dynamically place the Facebook root Div on the page (using jquery). You shouldn’t put it just anywhere in your theme (it messes with the Facebook dialog box ability to display over some content). I found that at the bottom of my page end body tag works best ($(‘body’).append(‘fb-root’) ‘psuedo code

  4. RilwisBy Rilwis on 24 June, 2011

    As you’re using jQuery, I think we should make the code more simpler using getScript() function to load JS asynchronously, like this:

    jQuery(document).ready(function($) {
      // Load LinkedIn button
      // Load Plus One Button
      // Load StumbleUpon button

    The getScript() function has a callback argument, so we can use it for tracking Twitter and Facebook actions like you did.

    I’m wondering why you don’t load FB javascript when the page is completed rendering like other scripts. Is the something problem here, or you just want to do it?

    By the way, the AddToAny does great job on tracking the add/share actions. It also has a plugin for WordPress, too. I think it’s worth to look at.

  5. Katinka HesselinkBy Katinka Hesselink on 24 June, 2011

    I’m sure if you turned this into a plugin a LOT of people would use it. ;) Especially since these five are definitely the top social sites in most niches. Though I have yet to hear reports on how well the Google social button actually works.

    • Haroun KolaBy Haroun Kola on 24 June, 2011

      Being a lazy designer, I’d love a plugin too :)

      • Do Business WithBy Do Business With on 30 June, 2011

        Another vote for a plugin please !
        Not a developer and not enough time to figure it out.
        ** Would happily pay for a comprehensive plugin like this

  6. NeilBy Neil on 24 June, 2011

    This is great, thanks, but the Facebook button doesn’t seem to be showing in Internet Explorer on Windows. I just ran tests on Adobe Browserlabs – both this page and my own test version with your code – and no sign of fb in IE.

    • Joost de ValkBy Joost de Valk on 25 June, 2011

      Any chance you could test whether it works now, and if not, tell me what (JavaScript) error you get?

      • NeilBy Neil on 25 June, 2011

        My apologies Joost. I am now on vacation with limited access. However I notice the FB Like problem with IE is well-documented via Google searches. .

  7. SueBy Sue on 24 June, 2011

    Your buttons look great Joost. Love the article – clear, concise and 1000x better than other articles as per usual.

    Have you come across the problem when using the Facebook like button that ?fb_xd_fragment= is added to the end of URLs and then shows a blank page?

    • Eivind SavioBy Eivind Savio on 24 June, 2011

      Really useful, Yoast. I had missed tracking of “Facebook Send” in my script.

      I have also found it useful to track “Facebook Unlike” to get a more correct number. It’s more or less like tracking “Facebook Like”:
      FB.Event.subscribe('edge.remove', function(response) {
      // Track Facebook Unlike
      _gaq.push(['_trackEvent','Facebook','Facebook UnLike',response,-1]);

      I have also include a -1 number in my code, and also uses +1 for Share or Likes. Not necessary, but I like to use numbers if I can.

      @Sue, check out or Google something like facebook channelURL fb_xd_fragment.

    • BryanBy Bryan on 24 June, 2011

      I’m wondering about the ?fb_xd_fragment= issue too. I understood a workaround for that was to specify a “channel URL” in FB.init that refers to a static HTML file on your site. It only needs to contain the line

      I’ve implemented this on my sites and it seems to clear up the problem. I wish FB would finally fix the dang bug though. It’s been a known issue for well over a year.

      • BryanBy Bryan on 24 June, 2011

        Oops, I meant to say the channel HTML file needs to contain only:

        • BryanBy Bryan on 24 June, 2011

          Sorry, was trying to post a javascript snippet, but it’s not working even using code tags.

  8. Shawn JordisonBy Shawn Jordison on 24 June, 2011

    Ah, my brain! I’m still going to try this though. Thanks!

  9. RamoonusBy Ramoonus on 25 June, 2011

    Hello Joost,
    will you be releasing a plugin which these functions?

  10. Bill RollinsBy Bill Rollins on 25 June, 2011

    Great info, thanks Joost. The Facebook buttons do not load in IE using this method. I’m testing with IE 8 and they do not load on your site either.

  11. Charles PayetBy Charles Payet on 26 June, 2011

    Gotta admit that most of this is over my head, but since I’ve REALLY been wanting to do what you describe here but didn’t have a clue……thank you for the great info, and hopefully I can figure it out!

  12. ArjenBy Arjen on 26 June, 2011

    Do you have the intention to develop a plugin for this?

  13. Joseph DowdyBy Joseph Dowdy on 26 June, 2011

    If you made plugins like this all day and charged $9.95 a month or $99 a year for this and your other extremely helpful plugins like WordPress SEO, I’d subscribe in an instant.

  14. EranBy Eran on 26 June, 2011

    Dude you are my new hero for this…

    Thank You

    Eran, a prolific non-coder of a blogger.

  15. BryanBy Bryan on 27 June, 2011

    Got this implemented on one of my sites, social button activity is being tracked in Google Analytics. Thanks, Joost, for the great information!

    • BryanBy Bryan on 27 June, 2011

      Just noticed my “Likes” are being recorded as “Shares” in Google Analytics. I found that “” is not part of the event response. Instead, it’s the URLs of my pages, so the check for a “Like” in the javascript is failing.

      I noticed your Open Graph metadata has a page ID. My site is set up as a Facebook application, so I have an app ID instead. Might have something to do with it.

      Combing through Facebook developer documentation to see if I can find an answer…

      • Joost de ValkBy Joost de Valk on 27 June, 2011

        Hmm keep me updated… That sounds “weird” but then again, that API is definitely not the best documented one on the planet.

        • BryanBy Bryan on 27 June, 2011

          No kidding!

          While I haven’t found a definitive answer, I am quite sure my hypothesis is correct. Namely, that I am getting the URLs of my posts in the ‘reponse’ parameter because of the way my site is set up as a Facebook application.

          I have no Facebook page or anything on associated with my site (that’s publicly accessible anyway). The URL of my Facebook application IS my site URL. I won’t claim to fully understand all the nuances of Open Graph at this point, but it appears OG enables Facebook to extend it’s reach to the general Web, no longer confined to the domain.

          I took a look at your Facebook page, and embedded in the code I found the page ID you are using in the Open Graph tags on your site. I believe “Likes” on your site are being associated with that page, hence “” is appearing in the ‘response’ parameter to the ‘edge.create’ event handler.

  16. MichielBy Michiel on 27 June, 2011

    I love this solution. Too bad most of the social buttons will break valdiation of (x)html, even if you implement the correct dtd and xmlns namespaces. I’d wish there is something that can be done about that, since customers prefer valid xhtml.

  17. MuskieBy Muskie on 27 June, 2011

    I at first did it by hand inside my theme, but switched to using the plugin Digg Digg so I can offload adding support for new buttons such as Google’s +1 to someone else. I don’t get that much traffic, but having done some guest blogging recently, I realize I get more than most people… ;-)

  18. josemvBy josemv on 27 June, 2011

    Hi Yoast, unfortunately it does not work in my case
    jQuery(document).ready(function($) {
    // Load Tweet Button Script
    var e = document.createElement('script');
    e.type="text/javascript"; e.async = true;
    e.src = '';

  19. josemvBy josemv on 27 June, 2011

    Sorry, tried to wrap my code with tags

  20. Simon VreemanBy Simon Vreeman on 29 June, 2011

    What do you of the information Google just published about social interaction tracking? Can we see this soon in your GA for WP plugin?

    • Joost de ValkBy Joost de Valk on 30 June, 2011

      Yeah looking at it at the moment. Don’t know whether that is actually something that should be in my plugin by default but I think I’ll add the option indeed.

      • ArjenBy Arjen on 1 July, 2011

        Then we need a template add-on with the correct social buttons code and allow the Analytics plugin to track these buttons. Correct?

  21. ArjenBy Arjen on 30 June, 2011
  22. Jeroen LaarhovenBy Jeroen Laarhoven on 30 June, 2011

    Don’t forget the xmlns:fb=”” attribute in the opening HTML tag, else IE9 (and others?) will not show the buttons.

    Can anyone help me out how to get the PlusOne button (tooltip) in a different language with this solution? Where/how do I configure the ‘{“lang”: “nl”}’?

    • JoseBy Jose on 30 June, 2011

      I solved this by adding e.innerHTML = "{lang: 'es-419'}"; replacing “es-419″ with the language code of your choice.

      • Jeroen LaarhovenBy Jeroen Laarhoven on 1 July, 2011

        Hmm, that was the first thing I tried … without result. But now I know it should work, I’ll look into it again. Thanx!

      • Jeroen LaarhovenBy Jeroen Laarhoven on 1 July, 2011

        Problem found: jquery $('head').append(e); does NOT work with the innerHTML, document.getElementsByTagName('head')[0].appendChild(e); does work OK.
        Conclusion: always follow Yoast blindly, do not think yourself ;).

  23. Susan SilverBy Susan Silver on 30 June, 2011

    This hurts my head a little bit, but I’ll work through it. I really want to do something similar using the buttons that work for my site. Ultimately it means I can get rid of one more plugin that may be slowing down my site. Also I really want those tracking stats. *lol*

  24. RaphaelBy Raphael on 30 June, 2011

    That sounds interesting Yoast, and I would like to implement it in my theme as well instead of using a plugin.

    I assume this code goes into single.php, doesn’t it?
    Also, want to use all the social icons you suggested. Where exactly do I have to add the ?

    Thanks so much in advance

  25. Andrea moroBy Andrea moro on 1 July, 2011

    Quite interesting article, but I wonder why you didn’t use the_ tracksocial event in ga. is there a reason for this?

  26. Cody SwannBy Cody Swann on 4 July, 2011

    We’re about 90% of the way to having this as a plugin. The OpenGraph support is a bit more robust and will let you specify what to share (video, image, etc), but other than that, it’s the same.

    If you’re interested, drop us a line, and I’ll let you know when it’s ready for production.

    I’ll come back here, and post it, too. Thanks for the great help J.

    • Cody SwannBy Cody Swann on 4 July, 2011

      As promised. Really raw. No docs and not sure how much support it will get, but if you want it:

      • Jeroen LaarhovenBy Jeroen Laarhoven on 22 July, 2011

        I used your and Yoast his code for implementing the buttons on (a Dutch site). This works fine in most browsers, but there are some issues:
        1) IE7 and IE8 do not like the dynamicly added attribs, resulting in no FB button. Workaround: put them into your html code.
        2) IE7 and others like Safari do not show the +1 button, but that seems also the case with static +1 buttons.

  27. Suraj NegiBy Suraj Negi on 5 July, 2011

    it is mobile site and i want plugin this app.

  28. DanBy Dan on 5 July, 2011

    Where do you put the Javascripts? Are they also in the template part, or just in the page footer?

  29. ToniBy Toni on 6 July, 2011 allows to easily add floating social buttons on any website

  30. Andrés SanhuezaBy Andrés Sanhueza on 9 July, 2011

    I was very bugged by these stuff lately. I personally never liked much adding social buttons on a site because they hardly match the design of the sites and I figured that there were few people using them and those who did had better ways to sharing stuff… until Twitter and Facebook surfaced, which unlike the others were much more mainstream. I don’t mind really having to add buttons for these two only, but while trying to update some of these buttons for a site yesterday I noticed that many services make the buttons much lesser customizable and with much dependency on external files (as with Google plus one, but especially Facebook), yet it seems that having them on the site do encourage most usage, but at the current stage for a design standpoint I would prefer not to use any of them, let alone the fact that there are always new ones and is confusing to keep track of the most useful.
    Sorry if this comment feels too off-topic, but I want to know your opinion on the subject.

  31. Luke RBy Luke R on 14 July, 2011

    Superb example of integration. I have just been updating a blog that was plugin heavy, and I am mainly a front end guy, so not to hot with php, but i did notice a few things in your code that caused issues. When clicking the ‘view source’ button for the markup, the twitter button has a space in the php call – data-text=”. There are also no ); on the javascript sections. Hope that helps other noobs like me :)

  32. SteveBy Steve on 14 July, 2011

    Ah – looks like you are suffering from the same tweet button popup blocking issue I am. The short is that in IE, when you use the bind function, the tweet (and follow) popups get blocked. I’ve posted it in their dev forum, and am waiting for a response.

  33. LarsBy Lars on 21 July, 2011


    thanks a lot for great article I searched for.

    For using in different languages I used follow links to generate:

    Change in
    <script src="″>
    xx_YY = de_DE or nl_NL aso.

    …{lang: ‘de’} or {lang: ‘nl’} aso.

    …data-lang=”de” or data-lang=”nl” aso