Shopify GA4 Event Tracking | Blue Frog Docs

Shopify GA4 Event Tracking

Track Shopify-specific events in GA4 including Shopify data layer events, theme events, and checkout events.

Shopify GA4 Event Tracking

Learn how to track Shopify-specific events in Google Analytics 4, including native data layer events, custom theme events, and checkout tracking.

Shopify Native Data Layer Events

Shopify provides a built-in data layer with several pre-configured events that fire automatically. These events use the window.dataLayer object.

Available Native Events

Event Name When It Fires Available On
page_viewed Every page load All pages
product_viewed Product detail page view Product pages
collection_viewed Collection page view Collection pages
search_submitted Search performed Search results
product_added_to_cart Item added to cart All pages with cart
product_removed_from_cart Item removed from cart Cart page
checkout_started Checkout begins Checkout (Plus only)
checkout_completed Order placed Order confirmation

Accessing Shopify Data Layer

The Shopify data layer is automatically available in window.dataLayer. Example structure:

window.dataLayer = [
  {
    event: 'page_viewed',
    page: {
      pageType: 'product',
      resourceType: 'product',
      resourceId: 1234567890
    },
    user: {
      customerId: null, // or customer ID if logged in
      customerEmail: null,
      customerFirstName: null,
      customerLastName: null
    }
  }
];

Mapping Shopify Events to GA4

GTM can listen to Shopify's data layer events and translate them to GA4 events.

1. Create Data Layer Variables

In GTM, create variables to capture Shopify data:

Variable: Page Type

  • Type: Data Layer Variable
  • Data Layer Variable Name: page.pageType
  • Name: DLV - Page Type

Variable: Product ID

  • Type: Data Layer Variable
  • Data Layer Variable Name: ecommerce.detail.products.0.id
  • Name: DLV - Product ID

Variable: Product Name

  • Type: Data Layer Variable
  • Data Layer Variable Name: ecommerce.detail.products.0.name
  • Name: DLV - Product Name

2. Create Custom Event Triggers

Trigger: Product Viewed

  • Type: Custom Event
  • Event name: product_viewed
  • Name: CE - Product Viewed

Trigger: Add to Cart

  • Type: Custom Event
  • Event name: product_added_to_cart
  • Name: CE - Add to Cart

Trigger: Remove from Cart

  • Type: Custom Event
  • Event name: product_removed_from_cart
  • Name: CE - Remove from Cart

3. Create GA4 Event Tags

Tag: GA4 - View Item

  • Type: Google Analytics: GA4 Event
  • Configuration Tag: \{\{GA4 Configuration Tag\}\}
  • Event Name: view_item
  • Event Parameters:
    • currency: \{\{Currency\}\} (from Shopify data layer)
    • value: \{\{Product Price\}\}
    • items: Use custom JavaScript or data layer products array
  • Trigger: CE - Product Viewed

Tag: GA4 - Add to Cart

  • Type: Google Analytics: GA4 Event
  • Configuration Tag: \{\{GA4 Configuration Tag\}\}
  • Event Name: add_to_cart
  • Event Parameters:
    • currency: \{\{Currency\}\}
    • value: \{\{Product Price\}\}
    • items: Products array from data layer
  • Trigger: CE - Add to Cart

Using Manual Theme Code

If not using GTM, you can listen to Shopify events and send to GA4 directly.

Add this to your theme.liquid after the GA4 initialization:

<script>
// Listen for Shopify data layer events
(function() {
  const originalPush = window.dataLayer.push;

  window.dataLayer.push = function() {
    const args = Array.prototype.slice.call(arguments);
    const event = args[0];

    // Call original push
    originalPush.apply(window.dataLayer, args);

    // Map Shopify events to GA4
    if (!event || !event.event) return;

    switch(event.event) {
      case 'product_viewed':
        handleProductViewed(event);
        break;
      case 'product_added_to_cart':
        handleAddToCart(event);
        break;
      case 'product_removed_from_cart':
        handleRemoveFromCart(event);
        break;
    }
  };

  function handleProductViewed(event) {
    if (!event.ecommerce || !event.ecommerce.detail) return;

    const product = event.ecommerce.detail.products[0];

    gtag('event', 'view_item', {
      currency: event.ecommerce.currencyCode || 'USD',
      value: parseFloat(product.price),
      items: [{
        item_id: product.id,
        item_name: product.name,
        item_brand: product.brand || '',
        item_category: product.category || '',
        item_variant: product.variant || '',
        price: parseFloat(product.price),
        quantity: 1
      }]
    });
  }

  function handleAddToCart(event) {
    if (!event.ecommerce || !event.ecommerce.add) return;

    const products = event.ecommerce.add.products;
    const items = products.map(p => ({
      item_id: p.id,
      item_name: p.name,
      item_brand: p.brand || '',
      item_category: p.category || '',
      item_variant: p.variant || '',
      price: parseFloat(p.price),
      quantity: p.quantity
    }));

    const totalValue = products.reduce((sum, p) => {
      return sum + (parseFloat(p.price) * p.quantity);
    }, 0);

    gtag('event', 'add_to_cart', {
      currency: event.ecommerce.currencyCode || 'USD',
      value: totalValue,
      items: items
    });
  }

  function handleRemoveFromCart(event) {
    if (!event.ecommerce || !event.ecommerce.remove) return;

    const products = event.ecommerce.remove.products;
    const items = products.map(p => ({
      item_id: p.id,
      item_name: p.name,
      price: parseFloat(p.price),
      quantity: p.quantity
    }));

    gtag('event', 'remove_from_cart', {
      currency: event.ecommerce.currencyCode || 'USD',
      items: items
    });
  }
})();
</script>

Custom Shopify Events

Beyond native events, you can track custom interactions specific to your store.

Newsletter Signup

Track newsletter form submissions:

<!-- In your newsletter form section -->
<script>
document.querySelector('#newsletter-form').addEventListener('submit', function(e) {
  gtag('event', 'newsletter_signup', {
    method: 'footer_form',
    location: '{{ template.name }}'
  });
});
</script>

Wishlist/Favorites

Track when customers add products to wishlists:

// When wishlist button is clicked
gtag('event', 'add_to_wishlist', {
  currency: '{{ cart.currency.iso_code }}',
  value: {{ product.price | money_without_currency }},
  items: [{
    item_id: '{{ product.id }}',
    item_name: '{{ product.title }}',
    price: {{ product.price | money_without_currency }},
    quantity: 1
  }]
});

Size/Variant Selection

Track when customers select product variants:

// Add to your product page JavaScript
document.querySelectorAll('input[name="id"]').forEach(function(radio) {
  radio.addEventListener('change', function() {
    const variant = JSON.parse(this.getAttribute('data-variant'));

    gtag('event', 'select_item', {
      item_list_name: 'Product Variants',
      items: [{
        item_id: variant.id,
        item_name: variant.title,
        item_variant: variant.option1 // Size, Color, etc.
      }]
    });
  });
});

Quick View Modal

Track quick view opens:

// When quick view is triggered
gtag('event', 'view_item', {
  item_list_name: 'Quick View',
  items: [{
    item_id: productId,
    item_name: productTitle
  }]
});

Store Locator Interactions

Track store locator searches:

gtag('event', 'store_locator_search', {
  search_term: searchQuery,
  results_count: storesFound.length
});

Checkout Events (Shopify Plus Only)

Shopify Plus stores with access to checkout.liquid can track detailed checkout events.

Begin Checkout Event

Fire when checkout starts:

<!-- In checkout.liquid -->
{% if checkout.step == 'contact_information' %}
<script>
  gtag('event', 'begin_checkout', {
    currency: '{{ checkout.currency }}',
    value: {{ checkout.total_price | money_without_currency }},
    items: [
      {% for line_item in checkout.line_items %}
      {
        item_id: '{{ line_item.product_id }}',
        item_name: '{{ line_item.title }}',
        item_variant: '{{ line_item.variant_title }}',
        price: {{ line_item.final_price | money_without_currency }},
        quantity: {{ line_item.quantity }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  });
</script>
{% endif %}

Add Shipping Info

Track when customer completes shipping information:

{% if checkout.step == 'shipping_method' %}
<script>
  gtag('event', 'add_shipping_info', {
    currency: '{{ checkout.currency }}',
    value: {{ checkout.total_price | money_without_currency }},
    shipping_tier: '{{ checkout.shipping_method.title }}',
    items: [
      {% for line_item in checkout.line_items %}
      {
        item_id: '{{ line_item.product_id }}',
        item_name: '{{ line_item.title }}',
        quantity: {{ line_item.quantity }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  });
</script>
{% endif %}

Add Payment Info

Track when customer reaches payment step:

{% if checkout.step == 'payment_method' %}
<script>
  gtag('event', 'add_payment_info', {
    currency: '{{ checkout.currency }}',
    value: {{ checkout.total_price | money_without_currency }},
    payment_type: 'credit_card', // or dynamically detect
    items: [
      {% for line_item in checkout.line_items %}
      {
        item_id: '{{ line_item.product_id }}',
        item_name: '{{ line_item.title }}',
        quantity: {{ line_item.quantity }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  });
</script>
{% endif %}

Order Confirmation (All Stores)

All Shopify stores can track purchases on the order confirmation page.

Settings → Checkout → Order status page → Additional scripts:

<script>
  gtag('event', 'purchase', {
    transaction_id: '{{ order.order_number }}',
    affiliation: '{{ shop.name }}',
    value: {{ total_price | money_without_currency }},
    currency: '{{ currency }}',
    tax: {{ tax_price | money_without_currency }},
    shipping: {{ shipping_price | money_without_currency }},
    items: [
      {% for line_item in line_items %}
      {
        item_id: '{{ line_item.sku }}',
        item_name: '{{ line_item.title }}',
        item_brand: '{{ line_item.vendor }}',
        item_category: '{{ line_item.product.type }}',
        item_variant: '{{ line_item.variant_title }}',
        price: {{ line_item.final_price | money_without_currency }},
        quantity: {{ line_item.quantity }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  });
</script>

Testing & Debugging

1. Use GA4 DebugView

Enable debug mode in GTM Preview or add:

gtag('config', 'G-XXXXXXXXXX', {
  'debug_mode': true
});

2. Check Browser Console

Monitor window.dataLayer in browser console:

// View all data layer pushes
console.log(window.dataLayer);

// Listen for new pushes
const originalPush = window.dataLayer.push;
window.dataLayer.push = function() {
  console.log('Data Layer Push:', arguments[0]);
  originalPush.apply(window.dataLayer, arguments);
};

3. Verify Event Parameters

In GA4 DebugView:

  • Check event name matches GA4 recommended events
  • Verify items array structure is correct
  • Confirm currency uses ISO 4217 codes (USD, EUR, GBP)
  • Check value is numeric without currency symbols

4. Test Full Funnel

  1. Product page → Verify view_item
  2. Add to cart → Verify add_to_cart
  3. View cart → Verify view_cart (if implemented)
  4. Begin checkout → Verify begin_checkout
  5. Complete purchase → Verify purchase

Common Issues

Events Fire Multiple Times

Cause: Multiple implementations (native + manual + GTM) or duplicate event listeners.

Fix:

  • Remove duplicate GA4 scripts
  • Use GTM to manage all events from one place
  • Check for duplicate event listeners in theme JavaScript

Missing Product Data

Cause: Shopify data layer structure varies by theme and page type.

Fix:

  • Log window.dataLayer to console to inspect structure
  • Adjust variable paths in GTM to match your theme's structure
  • Use fallback values for missing data

Checkout Events Don't Fire

Cause: Non-Plus store or incorrect checkout step detection.

Fix:

  • Verify you have Shopify Plus
  • Check checkout.step value matches your conditions
  • Test in actual checkout (not preview mode)

Next Steps

For general event tracking concepts, see GA4 Event Tracking Guide.

// SYS.FOOTER