Troubleshooting marketing attribution for Shopify

Updated on 2023-08-01

If your orders from Shopify in Google Analytics are attributed to the Direct or Unknown channel, or you are seeing strange clusters of 'orphan' events with no source, there are a few steps of Littledata's tracking that could be going wrong.

User versus Session attribution

Google Analytics 4 has two ways to look at marketing attribution:

  1. User acquisition: what was the first channel that brought the user (on that device) to your site, based on the First user default channel dimension

  2. Session acquisition: what was the channel that brought this current session, based on the Session default channel group dimension

For most cases User attribution is the most accurate long-term view.

Known limitations of marketing attribution

In the following situations we have no way of linking server-side events (including orders) to the preceding website visit, and so to the marketing channel that brought the user:

  1. When the order is from a source other than your own website; for example, one processed on Amazon Marketplace. You can see this by adding the custom dimension Payment gateway to the sales reports. You can block Littledata from processing these orders that don't go through the Shopify storefront.
  2. When the order is a recurring charge from a subscription which was set up before Littledata was installed (i.e. Littledata never tracked the session where the customer subscribed)
  3. When the user (or the user's browser) has blocked tracking scripts, so no events are sent from the user's browser
note:

Recurring orders in GA4 will only be attributed for subscriptions started after you set up the GA4 property, even if in Universal Analytics the subscription order had a known source.

In these cases you will see in Google Analytics:

  • The channel is Direct or Unassigned
  • The landing page for the session is (not set)
  • All dimensions set form the web browser (version, screen size etc) are (not set)
  • In the User Explorer report, the client ID starts with default.littledata

In Segment you will see that the anonymous ID starts with default.littledata

Why Littledata tracks non-attributable events

We create a unique client ID / anonymous ID for each user (starting with default.littledata). This identifier is persisted across all future events for that same user.

This allows you to understand post-checkout user behaviour, even if the original on-site journey was not tracked.

e.g. you can see all the recurring orders and upgrades that user made, but not the original marketing source of those orders.

Littledata's complete event tracking means you can measure accurate volumes of user activity (e.g. total revenue). Every web analytics system has similar limitations to the above - but our servers ensure that even when customers block scripts (does not want to be tracked), you can still anonymously include their orders in the total.

Issues to investigate

The following issues can all lead to an abnormal level (more than 10%) of events not linked to the pre-checkout web session.

Missing Littledata script

All pages need Littledata's script included in the Shopify theme - which populates the LittledataLayer with ecommerce data on that page.

tip:

    Go to the JavaScript console of the page in question and type in LittledataLayer into the console to see if it is defined.    

littledatalayer

Littledata’s script stores the client ID from Google Analytics’s cookie within the Shopify cart. Sometimes another app can overwrite the cart attributes leading to poor attribution.

tip:

    Request the current cart from Shopify and check that attributes field contains google-clientID (or segment-clientID)    

You can log the cart contents by pasting this snippet into the browser console:

var request = new XMLHttpRequest();
request.open("GET", "/cart.js", true);
request.onload = () => {
  var data = JSON.parse(request.responseText);
  data.attributes["google-clientID"] || data.attributes["segment-clientID"]
    ? console.log(data.attributes)
    : console.log("Client ID attribute missing");
};
request.send();

Client ID stored in cart attributes