Using the new Callbacks for Tracking

Sometimes you find surprising little things when you don’t expect it. Take this little gem:

Since 1.8.0 (released 19/1/17)

Added the following pre- and post-tracking call hooks. (AN-134567)
These functions take as parameters: the callback (a function), and the parameters to that function. For example:
s.registerPreTrackCallback(function(requestUrl,a,b,c) {
    console.log("pre track callback");
    console.dir(requestUrl); // Request URL
    console.dir(a); // param1
    console.dir(b); // param2
    console.dir(c); // param3
}, "param1", "param2", "param3");

The callback is invoked with the requestUrl and any parameters passed in when the callback is registered. This occurs either before or after the tracking call, depending on which method is used to register the callback. The order in which these callbacks are called is not guaranteed. Callbacks registered in the pre function are invoked after the final tracking URL is created. The post callbacks are called upon a successful tracking call (if the tracking call fails, these functions are not called). Any callback registered with registerPreTrackCallback do not affect the tracking call. Also, calling any of the tracking methods in any registered callback is not recommended and could cause an infinite loop.

Off the top of my head, I can think of these use cases for those callbacks:

  • Calling s.clearVars(), say with an SPA,
  • Integration with 3rd-party tools in the page, which need to know about the tracking parameters, or
  • Quality control, e.g. integration with a test framework

What the callbacks can not do is replace doPlugins().

From the description in the release notes, they are purely informational, i.e. they can see the tracking call with all parameters in all its glory, but they can not modify it like doPlugins() can.

Does that mean that my first use case won’t work?

Shall we test that?

Let’s test that!

Copies, copies

In order to test, I use this extremely simple page:

<!DOCTYPE html>
	<title>Testing postTrackCallback</title>
        <h1>Testing postTrackCallback</h1>
        <p>This page uses preTrackCallback and postTrackCallback. The question: Can those two modify the s object &mdash; say for s.clearVars()?</p> 
        <button onClick="trackClick(this); return false;">Click this!</button> 
        <p id="pre">Placeholder: pre track</p> 
        <p id="post">Placeholder: post track</p> 
        <script src="ptva.js"></script> 
        <script src="ptam.js"></script> 
                s.pageName="postTrackCallback Test"; 
                function trackClick(button) {
                        s.linkTrackEvents =; 
                        s.linkTrackVars = "events"; 
              , 'o', 'Click on button'); 
                s.registerPreTrackCallback(function(requestUrl, s) {
                        console.log("pre track callback");    
                        console.dir(requestUrl); // Request URL
//                      s.clearVars(); 
                        document.querySelector("#pre").innerText =; 
                }, s); 
                s.registerPostTrackCallback(function(requestUrl, s) { 
                        console.log("post track callback");     
                        console.dir(requestUrl); // Request URL     
                        document.querySelector("#post").innerText =; 
                }, s); 

It comes with standard Analytics tracking, the Marketing Cloud ID Service, plus a click handler for the button (which itself doesn’t do anything).

Pre- and postTrack callbacks output the tracking request URL, plus they print the value of the “variable” into the page. The postTrack callback also calls s.clearVars(), a function that cleans the s object and that is often uses with click tracking or in SPAs.

Here is the result:

Clicking the button – results
It looks like at the point where those callbacks are called, the system has copied all values from the s object into some temporary structure. Modifying the s object from the callbacks is possible, but it doesn’t impact what is tracked.

You can even call s.clearVars() in the preTrack callback, if you want. It’ll work as expected, but it won’t change the tracking, either.

The s object will be modified, though, and can therefore be prepped or mopped up according to your needs.

A tiny little gem, but very useful, if you ask me!

8 thoughts on “Using the new Callbacks for Tracking

    1. Hi Yuhui,

      Not quite. If I understand it correctly (based on Simo’s article, then customTask() is a lot more like the doPlugins construct for Adobe Analytics, see

      While doPlugins() and code inside this callback allows modification of tracked data, the preTrack and postTrack callbacks can NOT modify what is being sent.


  1. Keep in mind use of the s.registerPreTrackCallback() (Post version) “stack” instances (not the proper coding terminalogy I’m sure). What I mean is, if in your base implemetnation you include s.registerPreTrackCallback(“do function1”), it runs when s.t() is called. If you then have a rule for an onClick event which includes an s.registerPreTrackCallback(“do function2”), when the call is made both instances will run, so you get function1 and function2 running. Not a good or bad think, but WAS unexpected when I set up some pre and post callbacks for some testing I was doing. As far as I know there isn’t a way to remove an instance of a TrackCallback() on the page, so you are stuck with them. You could of course put in some additional logic by having the callback call a separate function, and maybe use the additional parameters in that call to feed it info, but that is kind of a separate issue.


    1. Hi Cleve,

      The callback is not attached to an individual tracking call. It is like s.doPlugins() in the sense that it gets attached to the s object as such.

      You can attach as many listeners as you’d like, but they will (as you saw) all be called.



    1. Works, thank you!

      Note that calling s.registerPreTrackCallback() (or Post, same thing) adds your callback function to the s object. You can do that at page load.

      If you do it inside s.doPlugins(), you’re actually adding multiple instances of your callback. I guess they will all be called in turn.

      Example: you add a callback that does console.log(request) in s.doPlugin()

      When the page loads, tracking happens, so your callback is registered once. Then a visitor clicks a tracked object. Another instance of your callback is registered. They click some other tracked object, and another instance is added. Your s object now has three callbacks to call on every tracking call!

      Probably not what you want.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.