Charles, It’s Not Just For Tag Validation – Part 2

In Part 1, we reviewed how Charles can be used to swap local files with files on your production site to test changes made to your tracking code.
Now, in Part 2, we will take the Map Local feature in Charles to a whole new level by mapping files that don’t yet exist on your site.
Using Map Local To Inject Tracking Scripts
Here is the scenario.  You need to test some data collection code and not only do you not have access to a development environment but none of your scripts are even on the site you need to track.  As a consultant, this comes up more than you may think.  Having the ability to code against a client’s site, without having deployed any tracking code, keeps you one step ahead of the game.  I could accept the inevitable and start saving local copies of the site…..or…..I can use Charles to inject my files into the site.  Yeah, let’s do that.
NOTE: This scenario is specific to injecting Omniture’s page tracking code but this process could be modified for use with other Vendor’s page tags.
Using the DigitalPulse Debugger, we can see that this site does not contain any Omniture tracking code.

1.  The first step is the identify a JS file we can hijack.  I’m using a Firefox plugin called JSView to quickly see all the scripts that are loaded on my site.

2.  I’ve decided I’m going to use the file ‘builder.js’.  So i’ll save a local copy of that file to my desktop.
3.  Add the following block of code to top of the the file (builder.js in my example):
loadScriptLibrary = function(src, targetElement, olFunction) {

if (typeof scriptElement == ‘undefined’) {

scriptElement = document.createElement(‘script’);

scriptElement.setAttribute(‘type’, ‘text/javascript’);
scriptElement.setAttribute(‘language’, ‘javascript’);
scriptElement.setAttribute(‘src’, src);
scriptElement.setAttribute(‘id’, src);

if (targetElement == null){
if (headElement == null)
headElement = document.getElementsByTagName(‘body’)[0];
targetElement = headElement;
var library = scriptElement.cloneNode(true);
library.src = src;
if(typeof olFunction == ‘function’){
if(! isIE){
olFunIE = olFunction.toString();
if(olFunIE.indexOf(‘function ‘)!= -1){
olFunIE = olFunIE.substr(‘function ‘.length);
olFunIE = olFunIE.substr(0, olFunIE.indexOf(‘)’)+1);
olFunIE = olFunIE.substr(olFunIE.indexOf(‘{‘)+1, olFunIE.lastIndexOf(‘}’)-(olFunIE.indexOf(‘{‘)+1));
library.onreadystatechange = function () {
if (library.readyState == ‘complete’ || library.readyState == ‘loaded’) {

loadScriptLibrary(“//”, document.getElementsByTagName(‘head’)[0]);


window.addEventListener(‘load’, trackingOnloadFunc, true);
4. Use Map Local in Charles to map your hijack file (builder.js in my example) on your site to the local copy we added the onload function to in step 3.

5.  Modify the tracking script (s_code.js).  In this step, you will add the logic to your s_code.js file that you want to test. For example, you can add plugins, add logic to set a page name, etc.  I’m adding a single line to set a page name:
As we are not using the standard Omniture page code, we also need to add a line to the bottom of the s_code.js file. If we don’t add this line, our files would load but no data would be sent to Omniture:
var s_code=s.t();if(s_code)document.write(s_code)
6. Again, we will use the Map Local feature in Charles to map the file we injected, the s_code.js file, in step 3. Line 44. Make sure you update this to reflect the location of the file on your site.

7. That should do it. Our hijack file loads, which in turns loads our data collection script. Now all we need to do is run the DigitalPulse Debugger to validate our code.

Code on my friends. Code. On.