9

It seems like:

ga('send', 'pageview');

Doesn't know how to handle large payload (over 8K), when we're sending a large transaction with more than 100 products, the page impression just tries to send all the items in a single beacon post.

products.forEach(product => ga('ec:addProduct', ...) ) // 100 products
ga('ec:setAction', 'purchase', ...)
ga('send', 'pageview');

Which results in

raven.js:80 Payload size is too large (11352).  Max allowed is 8192.

We are just following the documentation on: enhanced-ecommerce#measuring-transactions

Guy Korland
  • 9,139
  • 14
  • 59
  • 106
  • One way would be to make the checkout smaller - just pass the skus for each product and add names, category etc. via a data import (which as to be done before data collection, which is rather inconvenient if you add new products often). – Eike Pierstorff Sep 06 '16 at 08:33
  • Consider maybe importing xls/csv with products data to GA (in admin panel) ? https://support.google.com/analytics/answer/6066852?hl=en Then you can just send product ID with purchase (cause all other product parameters google will know from imported data) – Jacek Szymański Sep 06 '16 at 10:02
  • @EikePierstorff I can't do that the system is dynamic and new products can appear at any time – Guy Korland Sep 07 '16 at 10:26
  • Have you tried to foreach it ? In _gaq.push(['_addTrans', Your tracking string contains the unique order ID. It seems like that would associate them together properly. My question would be if the value for revenue can be the order total -- which would be ideal -- or if it will need to be the value for just the products you are sending which would be awkward. – cartalot Sep 10 '16 at 19:59

2 Answers2

4

The limit for a HTTP request to the Google Analytics endpoint is 8Kb (or more exactly 8192 bytes).
There is an excellent blog here discussing how to manage this overflow.
The idea is if the number of objects (products) in the array is larger than your defined number, let’s say 35, and a visitor has selected to show 100 products, the solution is to automatically send the data in 3 hits to avoid hitting the 8Kb limit.

<script>
if (product.length > 0 || promo.length > 0) {
    var maxProducts = 35;                   // Max objects that will be sent with 1 hit.
    var ecomm = product.concat(promo);      // Merge product & promo into 1 array that we use in the add to cart & click tracking.
while(product.length || promo.length) {
    var p1 = product.splice(0,maxProducts); // Split the product array into arrays with max 35 objects
    var p2 = promo.splice(0,maxProducts);   // Split the promo array into arrays with max 35 objects
    dataLayer.push({
        'ecommerce': {
            'promoView': {
                'promotions': p2
                },
            'impressions': p1
        },
        'event': 'impression', // GTM Event for Impression tracking
        'eventCategory':'Ecommerce','eventAction':'Impression'
        });
    };
};
</script>
Tony Vincent
  • 13,354
  • 7
  • 49
  • 68
  • 1
    I see how it's going to work for impressions but don't the products add and the purchase need to be grouped in a single event? – Guy Korland Sep 06 '16 at 04:23
2

After couple of tests it seems like we found the solution, we broke the transaction to batches of 20 items and at the end we send the transaction global data (like tax and shipping). Each batch is connected to the transaction by sending the transaction id.

            //break the transaction of batches of 20 items
            var idArrays = splitArray(Object.keys(cart.lines), 20),
                transaction = { id: order.id };
                angular.forEach(idArrays, function(ids){
                   angular.forEach(ids, function (id) {
                      var analyticsLine = analyticsCart(cart.lines[id]);
                      ga('ec:addProduct', analyticsLine);
                   });

                   // connect the batch to the transaction 
                   ga('ec:setAction', 'purchase', transaction);
                   ga('send', 'event', 'Checkout', 'Purchase', 'items batch');
                });

            //Send the transaction total data
            var fullTransaction = {
                id: order.id,
                tax: cart.tax,
                shipping: cart.deliveryCost
            };
            ga('ec:setAction', 'purchase', fullTransaction);
            ga('send', 'event', 'Checkout', 'Purchase', 'transaction details');
Guy Korland
  • 9,139
  • 14
  • 59
  • 106
  • 2
    In the past I found that multiple transactions with the same ID are displayed in one row, but are internally stored as multiple transactions (which affected some KPIs, e.g. Conversionrates). However in my case the transactions where sent with a few minutes between them. So I'm curious, have you tested that your transactions (which are presumably sent within milliseconds) are actually counted as a single order ? – Eike Pierstorff Sep 12 '16 at 12:48
  • @EikePierstorff you're right it does impact the conversion rate, did you find another workaround? – Guy Korland Jan 08 '17 at 20:20