Skip to main content
Solved

Migration from _learnq - Difference between klaviyo.track and klaviyo.put("track" ?


ross_hopkins
Active Contributor I
Forum|alt.badge.img+5

I updated Google Tag Manager based JavaScript to use the klaviyo object rather than _learnq a week ago. I have noticed a significant drop in the volume of events tracked against profiles since doing so.

 

I have read both https://developers.klaviyo.com/en/docs/introduction_to_the_klaviyo_object and https://developers.klaviyo.com/en/docs/javascript_api and I think I have become a little confused. Is there any difference between calling klaviyo.track(eventName, eventData) vs klaviyo.push(“track”, eventName, eventData)?

 

For more detail, on our website, an email address is added as a body attribute within the page code when a visitor is logged in. Therefore, I want to call identify with this email address if they are not already cookied before tracking an event. Otherwise, I only need to track the event (because a previous email click through to the site or form submission will have cookied the user/browser..?).

 

The original code I had didn’t cater for this:

<script type="text/javascript">
   var _learnq = window._learnq || [];
   var item = {
     "ProductName": "Pricing for Individuals",
     "Categories": ["Individual Pricing","Engagement","View","B2C"],
     "Action": "View",
     "URL": {{Page URL}},
     "page": {{Page Hostname}} + {{Page Path}},
     "path": {{Page Path}}
   };

   _learnq.push(["track", "Viewed Product", item]);
 </script>

 

And I have changed this to:

<script type="text/javascript">
function trackEvent(eventName, eventData) {
  klaviyo.track(eventName, eventData);
}

var eventName = "Viewed Product"; 
var emailStored = {{CJS - PRIMARY - Email}};

var eventData = {
  "ProductName": "Pricing for Individuals",
  "Categories": ["Individual Pricing", "Engagement", "View", "B2C"],
  "Action": "View",
  "URL": {{Page URL}},
  "page": {{Page Hostname}} + {{Page Path}},
  "path": {{Page Path}}
};

function trackKlaviyoEvent() {
  if (typeof klaviyo !== 'undefined') {
    if (emailStored) {
      klaviyo.identify({'email': emailStored}, function() {
        trackEvent(eventName, eventData);
      });
    } else {
      trackEvent(eventName, eventData);
    }
  }
}

// Track the event immediately
trackKlaviyoEvent();
</script>

What am I missing? I’m suspicious that the check for klaviyo being undefined might have something to do with this, but should I be calling klaviyo.track or klaviyo.push in the trackEvent function?

Thanks!

Ross

Best answer by Reid

Hello,

klaviyo.track and klaviyo.push(‘track’… will work the same. The return type on them is slightly different:

  • klaviyo.track will return a Promise, so I prefer to use this one. klaviyo.push does not and only allows for callbacks.

In your example snippet, I noticed you were checking if klaviyo is undefined. I’m wondering if this is the issue. Did you add the one line snippet here to your code? https://developers.klaviyo.com/en/docs/introduction_to_the_klaviyo_object#how-to-load-the-klaviyo-object

If you add this one line snippet to the top of your code, you should be able to use the klaviyo object without ever checking if it’s been intialized, and something like klaviyo.track can be used before klaviyo is loaded on the page.

If you aren’t using this one line snippet, it’s possible requests are being lost until klaviyo.js has fully loaded.

Hope that adds some clarity!

View original
Did this topic or the replies in the thread help you find an answer to your question?

6 replies

kaila.lawrence
Community Manager
Forum|alt.badge.img+31

@teamcooperuk I am SO sorry for the late reply here. You post was mistakenly flagged as spam by our system. I’m investigating why further. 

In the meantime, did you get this figured out?


ross_hopkins
Active Contributor I
Forum|alt.badge.img+5
  • Author
  • 2025 Champion
  • 11 replies
  • June 18, 2024

Hi Kalia,

Ah, I did wonder where my post went! 😀

I amended my code and my testing was successful - it seemed to behave as I expected, tracking me during the 2 scenarios I want it to:

  1. When I clicked on an email through to our site
  2. When I could use an email address available to me when I’m logged in but not cookied

However, I’m still seeing around a 50% drop-off in metric volume since making the switch from _learnq to klaviyo.push. I’m out of ideas at this point, so hoping the community can help!

This is the latest JS I have in place. This is just for one metric, but I use the same structure, simply changing eventName to a different value for other metrics:

<script type="text/javascript">
(function() {
    // Function to track event
    function trackEvent(eventName, eventData) {
        klaviyo.push(["track", eventName, eventData]);
    }

    // Function to check if Klaviyo is cookied
    function checkKlaviyoCookied(callback) {
        klaviyo.isIdentified().then(function(result) {
            callback(result);
        }).catch(function(error) {
            console.error("Klaviyo Tag: " + eventName + " - isIdentified error: ", error);
        });
    }

    // ** Replace the eventName & eventData values when copying the Tag for another metric ** //
    var eventName = "Viewed Product"; 
    var emailStored = {{CJS - PRIMARY - Email}};
    var debugMode = {{Debug Mode}};

    // ** If copying this tag, check the eventData! ** //
    var eventData = {
        "ProductName": "Pricing for Individuals",
        "Categories": ["Individual Pricing", "Engagement", "View", "B2C"],
        "Action": "View",
        "URL": {{Page URL}},
        "page": {{Page Hostname}} + {{Page Path}},
        "path": {{Page Path}}
    };
    // ** End of Event-Specific Variables **//

    // Variables required for every Event/Metric
    var debugMode = {{Debug Mode}};
    var emailStored = "{{CJS - PRIMARY - Email}}";
    var klaviyo = window.klaviyo || [];

    checkKlaviyoCookied(function(klaviyoCookied) {
        if (!klaviyoCookied && emailStored !== undefined && emailStored !== '') {
            // Register/Cookie the email address against this device  
            var debugText = "OUTCOME: Identify called with email - " + emailStored;
            klaviyo.identify({
                'email': emailStored
            }, function() {
                console.log("Klaviyo Tag: " + eventName + " - " + debugText);
                trackEvent(eventName, eventData);
            });
        } else if (!klaviyoCookied && (emailStored === undefined || emailStored === '')) {
            // Do nothing if the user is not cookied and no email is present
            var debugText = "OUTCOME: User not cookied and no email stored. Doing nothing.";
            console.log("Klaviyo Tag: " + eventName + " - " + debugText);
        } else {
            // User is cookied - id (_kx / _kla_id) used to track event/metric  
            var debugText = "OUTCOME: User identified/cookied, now tracking event";
            klaviyo.identify({}, function() {
                console.log("Klaviyo Tag: " + eventName + " - " + debugText);
                trackEvent(eventName, eventData);
            });
        }
    });
})();
</script>

 


Forum|alt.badge.img+31
  • Partner
  • 252 replies
  • June 19, 2024

Hello @teamcooperuk  My suggestion would be to manually identify the customer every time you want to track any event.

You are doing it the right way but remove the condition to check if email is Stored.

Klaviyo documentation says this:
 



Refer to this documentation for more info: https://developers.klaviyo.com/en/docs/javascript_api#api-basics


ross_hopkins
Active Contributor I
Forum|alt.badge.img+5
  • Author
  • 2025 Champion
  • 11 replies
  • June 19, 2024

Thanks @Maxbuzz 

I’ve adjusted the structure of my tag now - it’s quite different to what I initially posted. I have a post pending admin review - I think because of the amount of code it gets flagged. But I’ll try again….

I’m not sure I follow exactly.

I don’t always have access to an email address, so wouldn’t I need to check for that, because I’d need to call identify differently in each scenario:

 

With email stored:

 

if (!klaviyoCookied && emailStored !== undefined && emailStored !== '') {
            // Register/Cookie the email address against this device  
            klaviyo.identify({
                'email': emailStored
            }, function() {
                trackEvent(eventName, eventData);
            });

and when I don’t have access to an email address, but isIdentified returns true:

 

else {
            // User is cookied - id (_kx) used to track event/metric  
            klaviyo.identify({}, function() {
                trackEvent(eventName, eventData);
            });

 

I get that this is basic...I think I’ve been looking at this so long I have confused myself.


stephen.trumble
Community Manager
Forum|alt.badge.img+60

Hey @teamcooperuk 

So sorry your post’s haven’t been applied to the conversation happening. For some reason our “spam” filter has been a little aggressive, and anything with code keeps getting trapped. Working on a solution for this but just wanted to apologize for your work getting “stuck”. 


  • Klaviyo Employee
  • 1 reply
  • Answer
  • June 25, 2024

Hello,

klaviyo.track and klaviyo.push(‘track’… will work the same. The return type on them is slightly different:

  • klaviyo.track will return a Promise, so I prefer to use this one. klaviyo.push does not and only allows for callbacks.

In your example snippet, I noticed you were checking if klaviyo is undefined. I’m wondering if this is the issue. Did you add the one line snippet here to your code? https://developers.klaviyo.com/en/docs/introduction_to_the_klaviyo_object#how-to-load-the-klaviyo-object

If you add this one line snippet to the top of your code, you should be able to use the klaviyo object without ever checking if it’s been intialized, and something like klaviyo.track can be used before klaviyo is loaded on the page.

If you aren’t using this one line snippet, it’s possible requests are being lost until klaviyo.js has fully loaded.

Hope that adds some clarity!