Shopify Tracking Issues | Blue Frog Docs

Shopify Tracking Issues

Troubleshoot and resolve analytics tracking issues on Shopify websites.

Shopify Tracking Issues

Platform-specific guides for diagnosing and fixing analytics and tracking issues on Shopify.

Common Issues

Events Not Firing

Debug why analytics events aren't being captured on Shopify.

Shopify-Specific Tracking Challenges

Shopify's Liquid templating system and strict checkout restrictions create unique tracking scenarios that require platform-specific solutions.

Platform Code Injection Points

Shopify offers multiple locations for adding tracking code, each with different behaviors:

Theme Customization Code Injection:

  • Settings → Online Store → Preferences → Additional scripts (Checkout only, deprecated for checkout.liquid in Plus)
  • Theme.liquid head section (all pages except checkout for Basic/Standard plans)
  • Additional content & scripts sections in Theme Editor
  • Custom Liquid sections for granular control

Shopify Analytics Script Management:

// Available in theme.liquid head
{% if template contains 'product' %}
<script>
  // Product-specific tracking
  console.log('Product:', {{ product | json }});
</script>
{% endif %}

Code Location Restrictions by Plan:

Location Basic/Standard Shopify Plus
theme.liquid Available Available
checkout.liquid Not available Available
Customer events (Web Pixels) Available Available
Shopify Scripts Not available Available

Checkout Tracking Limitations

Non-Plus Plans:

  • Cannot edit checkout.liquid
  • Must use Additional Scripts (loads after checkout completion)
  • Cannot track individual checkout steps
  • Limited access to checkout data

Shopify Plus:

  • Full checkout.liquid access
  • Can track all checkout steps
  • Access to Liquid objects in checkout
  • Can modify checkout DOM

Code Example - Plus Checkout Tracking:

{% if first_time_accessed %}
<script>
dataLayer.push({
  event: 'checkout',
  ecommerce: {
    checkout: {
      actionField: {step: 1},
      products: [
        {% for line_item in line_items %}
        {
          id: '{{ line_item.product_id }}',
          name: '{{ line_item.title }}',
          price: '{{ line_item.price | money_without_currency }}',
          quantity: {{ line_item.quantity }}
        }{% unless forloop.last %},{% endunless %}
        {% endfor %}
      ]
    }
  }
});
</script>
{% endif %}

Theme Compatibility and Liquid Variables

Different Shopify themes have varying implementations:

Dawn Theme (Shopify 2.0):

  • Section-based architecture
  • Uses {{ content_for_header }} extensively
  • Supports app blocks
  • JSON-based theme structure

Vintage Themes:

Accessing Product Data:

<script>
{% if product %}
window.productData = {
  id: {{ product.id }},
  title: {{ product.title | json }},
  price: {{ product.price | money_without_currency }},
  compareAtPrice: {{ product.compare_at_price | money_without_currency }},
  vendor: {{ product.vendor | json }},
  type: {{ product.type | json }},
  tags: {{ product.tags | json }},
  variants: {{ product.variants | json }}
};
{% endif %}
</script>

Accessing Cart Data:

<script>
window.cartData = {{ cart | json }};
console.log('Cart item count:', {{ cart.item_count }});
console.log('Cart total:', {{ cart.total_price | money_without_currency }});
</script>

App Conflicts

Shopify's app ecosystem can create tracking conflicts:

Common Conflict Scenarios:

  • Multiple apps injecting Google Analytics (Facebook Channel, Google Channel, marketing apps)
  • Pixel apps conflicting with native tracking
  • Review apps modifying product page structure
  • Currency converter apps changing prices
  • Subscription apps modifying cart behavior

Diagnostic - Check Active Pixels:

// Shopify Web Pixels API
if (window.Shopify && window.Shopify.analytics) {
  console.log('Shopify Analytics:', window.Shopify.analytics);
}

// Check for multiple GA instances
const scripts = Array.from(document.querySelectorAll('script'));
const trackingScripts = scripts.filter(s =>
  s.src.includes('google-analytics.com') ||
  s.src.includes('googletagmanager.com') ||
  s.src.includes('facebook.net')
);
console.log('Found tracking scripts:', trackingScripts.length);
trackingScripts.forEach(s => console.log(s.src));

Customer Events (Web Pixels API)

Shopify's modern tracking approach using Customer Events:

Subscribe to Events:

// In Settings → Customer events → Add custom pixel
analytics.subscribe("page_viewed", (event) => {
  console.log("Page viewed:", event);
  // Your tracking code
});

analytics.subscribe("product_viewed", (event) => {
  console.log("Product viewed:", event.data.productVariant);
});

analytics.subscribe("product_added_to_cart", (event) => {
  console.log("Added to cart:", event.data.cartLine);
});

analytics.subscribe("checkout_started", (event) => {
  console.log("Checkout started:", event.data.checkout);
});

analytics.subscribe("checkout_completed", (event) => {
  console.log("Purchase:", event.data.checkout);
});

Advantages of Web Pixels:

  • Works on all pages including checkout (even non-Plus)
  • Loads in sandbox for better performance
  • Doesn't conflict with theme code
  • Survives theme changes

Comprehensive Diagnostic Checklist

1. Verify Code Injection Location

Check Theme Files:

# Look for tracking code in theme.liquid
# Admin → Online Store → Themes → Actions → Edit code
# Check these files:
# - layout/theme.liquid
# - snippets/google-analytics.liquid (if using snippet)
# - templates/product.liquid

Check Customer Events:

  • Settings → Customer events
  • Look for custom pixels
  • Verify pixel status is "Active"

Validation Code:

<!-- Add to theme.liquid to verify code location -->
<script>
console.log('Theme.liquid loaded');
console.log('Template:', '{{ template }}');
console.log('Customer:', {{ customer | json }});
</script>

2. Inspect Shopify Objects

// Check all available Shopify objects
console.log('Shopify object:', window.Shopify);
console.log('Shop:', window.Shopify.shop);
console.log('Theme:', window.Shopify.theme);
console.log('Currency:', window.Shopify.currency);

// Check Analytics object
if (window.Shopify.analytics) {
  console.log('Analytics meta:', window.Shopify.analytics.meta);
  console.log('Replayqueue:', window.Shopify.analytics.replayQueue);
}

// Check for product
if (window.meta && window.meta.product) {
  console.log('Product meta:', window.meta.product);
}

3. Monitor AJAX Cart Events

Shopify themes use AJAX for cart operations:

// Listen for AJAX cart events
document.addEventListener('DOMContentLoaded', function() {
  // Override fetch for cart requests
  const originalFetch = window.fetch;
  window.fetch = function(...args) {
    const url = args[0];
    if (typeof url === 'string' && url.includes('/cart/')) {
      console.log('Cart API call:', url);
    }
    return originalFetch.apply(this, args);
  };
});

// For themes using XMLHttpRequest
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
  if (url.includes('/cart/')) {
    console.log('XHR Cart call:', method, url);
  }
  return originalOpen.apply(this, arguments);
};

4. Check App Integrations

// Check for Facebook Pixel from multiple sources
console.log('Facebook Pixel:', window.fbq);

// Check for common Shopify app tracking
const appIndicators = [
  'Shopify.cdnHost',
  'BoostSDK', // Boost apps
  'SECOMAPP', // SEO apps
  'bsm', // Better Sales & Marketing
  'Stamped', // Reviews app
  'yotpo', // Reviews app
];

appIndicators.forEach(indicator => {
  if (window[indicator]) {
    console.log(`Found app indicator: ${indicator}`, window[indicator]);
  }
});

5. Test Checkout Tracking

For Non-Plus Stores:

<!-- In Additional Scripts section -->
{% if first_time_accessed %}
<script>
// This runs only on order confirmation page
console.log('Order:', {{ order | json }});
dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: '{{ order.order_number }}',
    value: {{ order.total_price | money_without_currency }},
    currency: '{{ shop.currency }}',
    tax: {{ order.tax_price | money_without_currency }},
    shipping: {{ order.shipping_price | money_without_currency }},
    items: [
      {% for line_item in order.line_items %}
      {
        item_id: '{{ line_item.product_id }}',
        item_name: '{{ line_item.title }}',
        price: {{ line_item.price | money_without_currency }},
        quantity: {{ line_item.quantity }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  }
});
</script>
{% endif %}

Browser DevTools Debugging Steps

Network Tab Analysis

1. Filter Tracking Requests:

Filter: /collect|/analytics|/batches|/tr?|/pixel

2. Inspect Shopify Analytics:

  • Look for monorail-edge.shopifysvc.com requests
  • These are Shopify's internal analytics
  • Check payload for customer privacy settings

3. Verify Third-Party Pixels:

  • Google Analytics: google-analytics.com/collect
  • Facebook: facebook.com/tr
  • TikTok: analytics.tiktok.com

Console Debugging

// Enable verbose logging for Shopify Analytics
if (window.Shopify && window.Shopify.analytics) {
  window.Shopify.analytics.publish = new Proxy(
    window.Shopify.analytics.publish,
    {
      apply: function(target, thisArg, args) {
        console.log('Shopify Analytics publish:', args);
        return target.apply(thisArg, args);
      }
    }
  );
}

// Debug dataLayer
if (window.dataLayer) {
  window.dataLayer.push = new Proxy(window.dataLayer.push, {
    apply: function(target, thisArg, args) {
      console.log('dataLayer push:', args);
      return target.apply(thisArg, args);
    }
  });
}

Application Tab Storage

Check Customer Privacy Settings:

// Shopify stores customer privacy preferences
const privacySettings = document.cookie.match(/_tracking_consent=([^;]+)/);
if (privacySettings) {
  console.log('Tracking consent:', decodeURIComponent(privacySettings[1]));
}

// Check for customer privacy banner
console.log('Privacy meta:', window.Shopify?.customerPrivacy);

Common Symptoms and Causes

Symptom Likely Cause Solution
No tracking on checkout Not using Shopify Plus Use Additional Scripts or Web Pixels API
Duplicate purchase events Multiple apps + manual code Audit apps and consolidate tracking
Wrong product prices Currency converter app Track before conversion or use original price
Cart events missing AJAX cart not tracked Implement fetch/XHR interceptors
Tracking only on homepage Code only in index.liquid Move to theme.liquid
Customer ID not tracked Customer not logged in Check {{ customer.id }} availability
Missing checkout steps Non-Plus plan Upgrade to Plus or use server-side tracking
Consent blocking all tracking Customer privacy banner Implement Shopify Customer Privacy API
Events fire twice Both theme code and Web Pixel Remove duplicate implementation
Data not in Liquid format Incorrect filter Use `

Tag Manager Troubleshooting

Google Tag Manager on Shopify

Installation Location:

<!-- In theme.liquid, right after <head> -->
{{ content_for_header }}

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
<!-- End Google Tag Manager -->

<!-- Immediately after <body> tag -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

Data Layer Implementation:

<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
  {% if customer %}
    customerId: '{{ customer.id }}',
    customerEmail: '{{ customer.email }}',
  {% endif %}
  pageType: '{{ request.page_type }}',
  shopCurrency: '{{ shop.currency }}'
});

{% if template contains 'product' %}
dataLayer.push({
  event: 'productDetail',
  ecommerce: {
    detail: {
      products: [{
        id: '{{ product.id }}',
        name: {{ product.title | json }},
        price: '{{ product.price | money_without_currency }}',
        variant: '{{ product.selected_or_first_available_variant.id }}'
      }]
    }
  }
});
{% endif %}
</script>

E-commerce Tracking Issues

Enhanced E-commerce Implementation

Product Impressions (Collection Pages):

{% if template contains 'collection' %}
<script>
dataLayer.push({
  event: 'productImpressions',
  ecommerce: {
    currencyCode: '{{ shop.currency }}',
    impressions: [
      {% for product in collection.products %}
      {
        id: '{{ product.id }}',
        name: {{ product.title | json }},
        price: '{{ product.price | money_without_currency }}',
        list: '{{ collection.title }}',
        position: {{ forloop.index }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  }
});
</script>
{% endif %}

Add to Cart Tracking:

// Using Shopify's AJAX API
document.querySelectorAll('form[action="/cart/add"]').forEach(form => {
  form.addEventListener('submit', function(e) {
    e.preventDefault();
    const formData = new FormData(this);

    fetch('/cart/add.js', {
      method: 'POST',
      body: formData
    })
    .then(response => response.json())
    .then(data => {
      console.log('Added to cart:', data);
      dataLayer.push({
        event: 'addToCart',
        ecommerce: {
          add: {
            products: [{
              id: data.product_id,
              name: data.product_title,
              price: (data.price / 100).toFixed(2),
              variant: data.variant_id,
              quantity: data.quantity
            }]
          }
        }
      });

      // Redirect to cart or show notification
      window.location.href = '/cart';
    });
  });
});

Purchase Tracking (Order Status Page):

{% if first_time_accessed %}
<script>
dataLayer.push({
  event: 'purchase',
  ecommerce: {
    purchase: {
      actionField: {
        id: '{{ order.order_number }}',
        affiliation: '{{ shop.name }}',
        revenue: '{{ order.total_price | money_without_currency }}',
        tax: '{{ order.tax_price | money_without_currency }}',
        shipping: '{{ order.shipping_price | money_without_currency }}',
        coupon: '{{ order.discount_applications[0].title }}'
      },
      products: [
        {% for line_item in order.line_items %}
        {
          id: '{{ line_item.product_id }}',
          name: {{ line_item.title | json }},
          price: '{{ line_item.price | money_without_currency }}',
          variant: '{{ line_item.variant_id }}',
          quantity: {{ line_item.quantity }},
          sku: '{{ line_item.sku }}'
        }{% unless forloop.last %},{% endunless %}
        {% endfor %}
      ]
    }
  }
});
</script>
{% endif %}

Shopify Customer Privacy API

Check Privacy Settings:

// Modern approach using Shopify's Customer Privacy API
if (window.Shopify && window.Shopify.customerPrivacy) {
  const privacy = window.Shopify.customerPrivacy;

  // Check current consent
  privacy.currentVisitorConsent().then(consent => {
    console.log('Current consent:', consent);
    console.log('Analytics allowed:', consent.analytics);
    console.log('Marketing allowed:', consent.marketing);
    console.log('Preferences allowed:', consent.preferences);
    console.log('Sale of data allowed:', consent.sale_of_data);
  });

  // Set consent
  privacy.setTrackingConsent({
    analytics: true,
    marketing: false,
    preferences: true,
    sale_of_data: false
  });
}

Conditional Tracking Based on Consent:

function initializeTracking() {
  if (window.Shopify && window.Shopify.customerPrivacy) {
    window.Shopify.customerPrivacy.currentVisitorConsent().then(consent => {
      if (consent.analytics) {
        // Load Google Analytics
        loadGoogleAnalytics();
      }
      if (consent.marketing) {
        // Load Facebook Pixel
        loadFacebookPixel();
      }
    });
  } else {
    // Fallback if API not available
    loadGoogleAnalytics();
  }
}

document.addEventListener('DOMContentLoaded', initializeTracking);

Google Consent Mode Integration:

<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

// Set default consent
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'analytics_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied'
});

// Update based on Shopify privacy settings
if (window.Shopify && window.Shopify.customerPrivacy) {
  window.Shopify.customerPrivacy.currentVisitorConsent().then(consent => {
    gtag('consent', 'update', {
      'analytics_storage': consent.analytics ? 'granted' : 'denied',
      'ad_storage': consent.marketing ? 'granted' : 'denied',
      'ad_user_data': consent.marketing ? 'granted' : 'denied',
      'ad_personalization': consent.marketing ? 'granted' : 'denied'
    });
  });
}
</script>

When to Contact Support

Contact Shopify Support When:

Platform-Level Issues:

  • Theme code changes not saving
  • Customer events not appearing in settings
  • Checkout pages returning errors
  • Apps not installing properly

Provide to Shopify:

  1. Store URL (.myshopify.com)
  2. Theme name and version
  3. Screenshots of code editor
  4. List of installed apps
  5. Specific page URLs with issues

Contact Analytics Vendor When:

  • Events firing correctly but not in reports
  • Data attribution errors
  • Report discrepancies
  • API integration issues

Provide to Vendor:

  1. Example tracking requests (from Network tab)
  2. Console logs showing event data
  3. Property/Account IDs
  4. Timeline of when issue started

Contact Theme Developer When:

  • Custom theme missing Liquid objects
  • Theme conflicts with tracking code
  • Template modifications not working
  • AJAX cart customizations needed

Provide to Developer:

  1. Theme name and purchase details
  2. Code changes attempted
  3. Desired tracking behavior
  4. Browser console errors

General Fixes

For universal tracking concepts, see the Global Tracking Issues Hub.

// SYS.FOOTER