When creating ChoiceVoice we wanted to greatly simplify the order process. Wojtek decided to fit it all on single page powered by Ajax. This worked out great, but at the end of the implementation we faced a minor problem. Google’s Adwords don’t support programmatic conversion tracking. With the snippet provided by Google the user triggers conversion by navigating to a site - like a “Thank you for your order” page. This of course couldn’t work for us, because our clients are taken to PayPal immediately after filling out the form.

The snippet that Google provides is really simple. Most of it is JavaScript itself, so why not execute it from our own code? Let’s take a look:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 1234567890;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "ABCDEFGHIJKlmnop-qr";
var google_conversion_value = 0;
/* ]]> */
</script>
<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="http://www.googleadservices.com/pagead/conversion/1234567890/?label=ABCDEFGHIJKlmnop-qr&amp;guid=ON&amp;script=0"/>
</div>
</noscript>

One way of triggering the conversion would be to insert the image that Google falls back to in the <noscript> tag. This would work, but I assume that this fallback method is somehow inferior to the functionality offered by the included conversion.js script (I’ve noticed that it is requesting some additional resources).

The other method would be to add something like this to your JavaScript files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var google_conversion_id = 1234567890;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "";
var google_conversion_value = 0;

var conversionLabels = {
  'voice-order': "ABCDEFGHIJKlmnop-12",
  'copy-order': "ABCDEFGHIJKlmnop-23"
};


function trackConversion(label) {
  google_conversion_label = conversionLabels[label];
  $.getScript('https://www.googleadservices.com/pagead/conversion.js');
};

/* then somewhere in your UI code: */
trackConversion('voice-order');

This code assumes that you’re using jQuery or something that provides the $.getScript() function. And also… it does not work. If you use this code to execute the conversion on user interaction, your page will end up blank. The user will be left with a white screen. Obviously not what we want him to see after placing an order with us.

After some digging around I found out that the problem was Google’s conversion.js calling document.write(). This function usually appends text to the document’s body, but there’s a catch. If the document is fully loaded it won’t append, but instead it will start a new document replacing the one currently displayed. There’s a reason for that - you probably don’t want to append anything after the </html> tag.

But Google’s conversion.js assumes that it is included inside the document’s body and while the document is still being loaded. A solution is to overwrite the default document.write() method. A fairly simple task and surprisingly safe.

In the end our trackConversion() function should look like this:

1
2
3
4
5
6
7
8
function trackConversion(label) {
  google_conversion_label = conversionLabels[label];

  document.write = function(text) {
    $('#content').append(text);
  };
  $.getScript('https://www.googleadservices.com/pagead/conversion.js');
};

The code allows you to have different conversions and select which one you want to trigger. With little effort you can add a second argument to trackConversion that will assign conversion value.