Skip to content

Shopify Double-Tracking Prevention

Shopify double-tracking happens when you run both a Shopify GA4 app (like the official Google channel) and a Custom Pixel with GTM that also sends GA4 events.

Here’s what’s happening:

  • The Shopify app injects its own gtag.js on every page, firing page_view, purchase, add_to_cart automatically
  • Your Custom Pixel loads GTM, which fires a GA4 Config tag on “All Pages”
  • Both fire identical events simultaneously

Result: every GA4 event fires twice, doubling your numbers and breaking downstream analysis.

  1. Check GA4 DebugView: Open DebugView and load a page. You’ll see pairs of identical events arriving within milliseconds of each other.

  2. Check Network tab: Filter requests to collect requests to google-analytics.com. Count the hits per page load—you should see roughly 2x the expected number.

  3. Check GA4 Reports: Look at your page_view counts. Inflated numbers (roughly 2x expected traffic) are the telltale sign.

  4. Query BigQuery: Run this diagnostic on yesterday’s data:

    SELECT
    event_date,
    event_name,
    user_pseudo_id,
    event_timestamp,
    COUNT(*) as event_count
    FROM `project.dataset.events_*`
    WHERE _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
    AND event_name IN ('page_view', 'purchase', 'begin_checkout')
    GROUP BY 1, 2, 3, 4
    HAVING event_count > 1
    ORDER BY event_count DESC
    LIMIT 100

    Duplicates with identical event_timestamp values confirm double-tracking.

Fix #1: Change GA4 Config Trigger (Simplest)

Section titled “Fix #1: Change GA4 Config Trigger (Simplest)”

The quickest fix is to prevent GTM’s GA4 Config from firing on every page:

  1. Open Google Tag Manager and edit your Google Tag (GA4 Config tag)
  2. Change the trigger from “All Pages” to a Custom Event trigger—use something like cookie_consent_update or consent_granted
  3. This way GTM’s GA4 only initializes after consent, avoiding conflict with the Shopify app’s automatic tracking

This works because the Shopify app already handles initial page_view events. Your GTM tag now only fires when explicitly triggered, preventing duplication.

Use Shopify’s app for storefront tracking and Custom Pixels ONLY for checkout:

EventSourceReason
page_viewShopify AppAlready injected, no duplication
view_itemShopify AppProduct pages, native integration
add_to_cartShopify AppAutomatic firing on cart add
begin_checkoutCustom PixelCheckout page only, GTM control
add_shipping_infoCustom PixelGTM-powered consent handling
add_payment_infoCustom PixelGTM-powered consent handling
purchaseCustom PixelCustom transaction handling

This creates a clean handoff: the Shopify app owns the storefront, your Custom Pixel owns the checkout funnel. No overlap.

Fix #3: Transaction ID Deduplication (Safety Net)

Section titled “Fix #3: Transaction ID Deduplication (Safety Net)”

Even with the hybrid approach, add deduplication logic to your purchase handler as a backstop:

// In your Custom Pixel purchase handler
analytics.subscribe('checkout_completed', (event) => {
const orderId = event.data.checkout.order?.id || event.data.checkout.token;
// Check if this transaction was already sent
// (using pixel's own storage since sessionStorage isn't available)
if (window.__trackedOrders && window.__trackedOrders[orderId]) {
console.log('Duplicate purchase blocked:', orderId);
return;
}
window.__trackedOrders = window.__trackedOrders || {};
window.__trackedOrders[orderId] = true;
// Proceed with purchase event push
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: 'purchase',
ecommerce: { /* ... */ }
});
});

This blocks any purchase event with the same orderId from firing twice in the same session.

GA4 automatically deduplicates purchase events with identical transaction_id values within a session. However, this only applies to purchase events. Other events like page_view and begin_checkout have no built-in deduplication, so you must prevent duplicates at the source.

  1. Diagnose using DebugView, Network tab, and BigQuery
  2. Fix with GTM trigger isolation (quickest) or hybrid approach (cleanest)
  3. Add transaction deduplication for purchase safety
  4. Test in incognito with one tracking method at a time

Double-tracking isn’t a bug—it’s a config issue. Fix the source, not the data.