Installing Google Analytics 4 on WooCommerce | OpsBlu Docs

Installing Google Analytics 4 on WooCommerce

Complete guide to implementing GA4 on WooCommerce stores using plugins, manual integration, or GTM

This guide covers WooCommerce-specific methods for implementing Google Analytics 4 (GA4) with full eCommerce tracking capabilities.

Prerequisites

Before installing GA4 on WooCommerce:

  1. Create a GA4 Property with eCommerce enabled

    • Sign in to analytics.google.com
    • Create a new GA4 property
    • Enable eCommerce in Data Streams settings
    • Copy your Measurement ID (format: G-XXXXXXXXXX)
  2. Choose Your Implementation Method based on:

    • Technical expertise level
    • Need for custom product tracking
    • Performance requirements
    • Existing WooCommerce setup

Best for: Non-technical users, automatic eCommerce tracking, quick setup

Why MonsterInsights for WooCommerce?

Installation Steps

  1. Install MonsterInsights

    • Navigate to Plugins → Add New
    • Search for "MonsterInsights"
    • Install and activate (Pro version required for eCommerce)
  2. Connect to Google Analytics

    • Click MonsterInsights → Settings
    • Click Connect with Google
    • Authenticate and select your GA4 property
  3. Enable WooCommerce Tracking

    • Go to MonsterInsights → Settings → eCommerce
    • Enable Use Enhanced eCommerce
    • Enable the following events:
      • Product Impressions
      • Product Clicks
      • Add to Cart
      • Remove from Cart
      • Checkout Steps
      • Purchases
  4. Configure Advanced Options

    Settings → eCommerce:
    - Track add to cart events: Yes
    - Track remove from cart events: Yes
    - Track checkout steps: Yes
    - Track purchases: Yes
    - Use SKU instead of ID: Optional (recommended)
    
  5. Verify Installation

    • Visit your WooCommerce store
    • Add a product to cart
    • Check Google Analytics → Reports → Realtime → Events
    • Confirm add_to_cart event appears

MonsterInsights Custom Tracking

// Add custom dimension for customer type
add_action('wp_footer', 'mi_custom_customer_dimension');
function mi_custom_customer_dimension() {
    if (is_user_logged_in()) {
        $customer = new WC_Customer(get_current_user_id());
        $order_count = $customer->get_order_count();
        $customer_type = $order_count > 0 ? 'returning' : 'new';
        ?>
        <script>
            if (typeof gtag !== 'undefined') {
                gtag('set', 'user_properties', {
                    'customer_type': '<?php echo $customer_type; ?>',
                    'total_orders': <?php echo $order_count; ?>
                });
            }
        </script>
        <?php
    }
}

MonsterInsights Limitations

  • Requires Pro version for eCommerce ($199+/year)
  • Cannot customize tracking code or add custom event parameters without editing plugin source
  • Adds plugin overhead (~200 KB)
  • Dashboard reports don't match GA4 exactly

Method 2: WooCommerce Google Analytics Integration

Best for: Official WooCommerce solution, built by WooCommerce team

Installation

  1. Install the Plugin

    • Go to Plugins → Add New
    • Search "WooCommerce Google Analytics Integration"
    • Install and activate (free)
  2. Configure Settings

    • Navigate to WooCommerce → Settings → Integration → Google Analytics
    • Enter your Measurement ID (G-XXXXXXXXXX)
  3. Enable Tracking Options

    Settings:
    ✓ Enable Universal Analytics Tracking
    ✓ Enable GA4 Tracking
    ✓ Track eCommerce events
    ✓ Track add to cart events
    ✓ Track remove from cart events
    ✓ Enable enhanced eCommerce tracking
    
    Advanced:
    ✓ Use SKU instead of Product ID
    ✓ Track 404 errors
    ✓ Track user ID
    
  4. AJAX Cart Fragment Handling

    This plugin automatically handles WooCommerce AJAX cart updates:

    // Plugin handles this automatically, but you can customize:
    add_filter('woocommerce_google_analytics_event_data', 'custom_ga_event_data', 10, 3);
    function custom_ga_event_data($data, $event_name, $product) {
        // Add custom parameters
        $data['custom_parameter'] = 'custom_value';
        return $data;
    }
    

Advanced Configuration

// Disable tracking for specific user roles
add_filter('woocommerce_ga_disable_tracking', 'disable_ga_for_roles', 10, 1);
function disable_ga_for_roles($disable) {
    if (current_user_can('manage_woocommerce')) {
        return true; // Don't track shop managers
    }
    return $disable;
}

// Track product variations separately
add_filter('woocommerce_google_analytics_product_id', 'use_variation_id', 10, 2);
function use_variation_id($product_id, $product) {
    if ($product->is_type('variation')) {
        return $product->get_id(); // Use variation ID instead of parent
    }
    return $product_id;
}

Method 3: Manual WooCommerce Integration

Best for: Developers, full control, custom tracking, performance optimization

Child Theme Setup

1. Create functions.php in child theme:

<?php
// Add GA4 tracking code
add_action('wp_head', 'wc_add_ga4_tracking', 1);
function wc_add_ga4_tracking() {
    // Don't track admins/shop managers
    if (current_user_can('manage_woocommerce')) {
        return;
    }

    $measurement_id = 'G-XXXXXXXXXX';
    ?>
    <!-- Google Analytics 4 for WooCommerce -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=<?php echo $measurement_id; ?>"></script>
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', '<?php echo $measurement_id; ?>', {
            'send_page_view': true,
            'allow_google_signals': true
        });
    </script>
    <?php
}

Track Product Views

// Track product detail views
add_action('woocommerce_after_single_product', 'track_product_view');
function track_product_view() {
    global $product;

    if (!$product) return;

    $product_data = array(
        'item_id' => $product->get_sku() ? $product->get_sku() : $product->get_id(),
        'item_name' => $product->get_name(),
        'price' => $product->get_price(),
        'item_category' => get_product_category($product),
        'item_variant' => get_product_variant($product)
    );
    ?>
    <script>
        gtag('event', 'view_item', {
            currency: '<?php echo get_woocommerce_currency(); ?>',
            value: <?php echo $product->get_price(); ?>,
            items: [<?php echo json_encode($product_data); ?>]
        });
    </script>
    <?php
}

function get_product_category($product) {
    $categories = get_the_terms($product->get_id(), 'product_cat');
    return $categories && !is_wp_error($categories) ? $categories[0]->name : '';
}

function get_product_variant($product) {
    if ($product->is_type('variation')) {
        return $product->get_attribute_summary();
    }
    return '';
}

Track Add to Cart (AJAX-Compatible)

WooCommerce uses AJAX for add to cart, so standard tracking won't work:

// Track AJAX add to cart
add_action('wp_footer', 'track_ajax_add_to_cart');
function track_ajax_add_to_cart() {
    if (!is_product() && !is_shop() && !is_product_category()) {
        return;
    }
    ?>
    <script>
        jQuery(document.body).on('added_to_cart', function(event, fragments, cart_hash, $button) {
            // Get product data from button
            var product_id = $button.data('product_id');
            var product_name = $button.data('product_name') || $button.attr('aria-label');
            var quantity = $button.data('quantity') || 1;

            // Fire GA4 event
            gtag('event', 'add_to_cart', {
                currency: '<?php echo get_woocommerce_currency(); ?>',
                items: [{
                    item_id: product_id,
                    item_name: product_name,
                    quantity: quantity
                }]
            });
        });
    </script>
    <?php
}

Track Cart Changes on Cart Page

// Add tracking data to cart page
add_action('woocommerce_after_cart', 'track_cart_view');
function track_cart_view() {
    $cart = WC()->cart;

    if ($cart->is_empty()) {
        return;
    }

    $items = array();
    foreach ($cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $items[] = array(
            'item_id' => $product->get_sku() ? $product->get_sku() : $product->get_id(),
            'item_name' => $product->get_name(),
            'price' => $product->get_price(),
            'quantity' => $cart_item['quantity']
        );
    }
    ?>
    <script>
        gtag('event', 'view_cart', {
            currency: '<?php echo get_woocommerce_currency(); ?>',
            value: <?php echo $cart->get_cart_contents_total(); ?>,
            items: <?php echo json_encode($items); ?>
        });
    </script>
    <?php
}

Track Checkout Initiation

// Track begin_checkout event
add_action('woocommerce_before_checkout_form', 'track_begin_checkout');
function track_begin_checkout() {
    $cart = WC()->cart;
    $items = array();

    foreach ($cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $items[] = array(
            'item_id' => $product->get_sku() ? $product->get_sku() : $product->get_id(),
            'item_name' => $product->get_name(),
            'price' => $product->get_price(),
            'quantity' => $cart_item['quantity']
        );
    }
    ?>
    <script>
        gtag('event', 'begin_checkout', {
            currency: '<?php echo get_woocommerce_currency(); ?>',
            value: <?php echo $cart->get_total('raw'); ?>,
            items: <?php echo json_encode($items); ?>
        });
    </script>
    <?php
}

Track Purchases

// Track purchase on thank you page
add_action('woocommerce_thankyou', 'track_purchase', 10, 1);
function track_purchase($order_id) {
    if (!$order_id) {
        return;
    }

    // Prevent duplicate tracking on page refresh
    if (get_post_meta($order_id, '_ga4_tracked', true)) {
        return;
    }

    $order = wc_get_order($order_id);
    $items = array();

    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        $items[] = array(
            'item_id' => $product->get_sku() ? $product->get_sku() : $product->get_id(),
            'item_name' => $item->get_name(),
            'price' => $item->get_total() / $item->get_quantity(),
            'quantity' => $item->get_quantity()
        );
    }
    ?>
    <script>
        gtag('event', 'purchase', {
            transaction_id: '<?php echo $order->get_order_number(); ?>',
            value: <?php echo $order->get_total(); ?>,
            currency: '<?php echo $order->get_currency(); ?>',
            tax: <?php echo $order->get_total_tax(); ?>,
            shipping: <?php echo $order->get_shipping_total(); ?>,
            items: <?php echo json_encode($items); ?>
        });
    </script>
    <?php

    // Mark as tracked
    update_post_meta($order_id, '_ga4_tracked', true);
}

Method 4: Google Tag Manager

Best for: Marketing teams, multiple tracking platforms, flexibility

See the dedicated GTM Setup Guide for WooCommerce-specific GTM implementation with data layer.

Quick Setup Overview:

  1. Install GTM container code
  2. Configure WooCommerce data layer
  3. Add GA4 Configuration Tag
  4. Set up eCommerce event triggers

WooCommerce-Specific Considerations

Cart Fragments and AJAX

WooCommerce updates the cart via AJAX without page reloads:

// Hook into cart fragments for tracking
add_filter('woocommerce_add_to_cart_fragments', 'update_tracking_fragment');
function update_tracking_fragment($fragments) {
    // Add tracking data to AJAX response
    ob_start();
    ?>
    <script>
        // Custom tracking code executed after AJAX cart update
        console.log('Cart updated via AJAX');
    </script>
    <?php
    $fragments['script.ga-cart-update'] = ob_get_clean();
    return $fragments;
}

Product Variations

Track variations separately for detailed analytics:

// Handle variable products
add_action('woocommerce_after_add_to_cart_button', 'track_variation_selection');
function track_variation_selection() {
    global $product;

    if (!$product->is_type('variable')) {
        return;
    }
    ?>
    <script>
        jQuery('.variations_form').on('found_variation', function(event, variation) {
            gtag('event', 'view_item', {
                items: [{
                    item_id: variation.sku || variation.variation_id,
                    item_name: variation.variation_description,
                    item_variant: variation.attributes,
                    price: variation.display_price
                }]
            });
        });
    </script>
    <?php
}

WooCommerce Subscriptions

Track recurring revenue separately:

// Track subscription signups
add_action('woocommerce_subscription_status_active', 'track_subscription_signup', 10, 1);
function track_subscription_signup($subscription) {
    // Only track new subscriptions, not renewals
    if ($subscription->get_date('date_created') !== $subscription->get_date('last_order_date_created')) {
        return;
    }
    ?>
    <script>
        gtag('event', 'subscribe', {
            value: <?php echo $subscription->get_total(); ?>,
            currency: '<?php echo $subscription->get_currency(); ?>',
            subscription_id: '<?php echo $subscription->get_id(); ?>',
            billing_period: '<?php echo $subscription->get_billing_period(); ?>'
        });
    </script>
    <?php
}

Performance Optimization

// Delay GA4 loading for better performance
add_action('wp_footer', 'delay_ga4_woocommerce', 99);
function delay_ga4_woocommerce() {
    ?>
    <script>
        // Load GA4 after user interaction
        let gaLoaded = false;
        const loadGA = () => {
            if (gaLoaded) return;
            gaLoaded = true;

            const script = document.createElement('script');
            script.async = true;
            script.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX';
            document.head.appendChild(script);

            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', 'G-XXXXXXXXXX');
        };

        // Load on scroll, click, or after 3 seconds
        ['scroll', 'click', 'touchstart'].forEach(event => {
            window.addEventListener(event, loadGA, {once: true, passive: true});
        });
        setTimeout(loadGA, 3000);
    </script>
    <?php
}

Validation and Testing

1. Test WooCommerce Events

Complete a full purchase flow:

  1. Browse products → Check view_item_list event
  2. View product → Check view_item event
  3. Add to cart → Check add_to_cart event
  4. View cart → Check view_cart event
  5. Begin checkout → Check begin_checkout event
  6. Complete purchase → Check purchase event

2. Real-Time Reports

  • Navigate to GA4 → Reports → Realtime → Events
  • Perform WooCommerce actions
  • Verify events appear within 30 seconds

3. GA4 DebugView

Enable debug mode:

// Add to your site temporarily
gtag('config', 'G-XXXXXXXXXX', {
    'debug_mode': true
});

Then check GA4 → Configure → DebugView

4. Check eCommerce Data

After 24-48 hours:

  • GA4 → Reports → Monetization → Ecommerce Purchases
  • Verify revenue, transactions, and product data

Common Issues

Events Fire Twice

Cause: Multiple tracking implementations (plugin + manual code) Solution: Choose one method and remove others

Purchase Event on Every Page Reload

Cause: No deduplication logic Solution: Use update_post_meta($order_id, '_ga4_tracked', true); as shown above

AJAX Cart Not Tracked

Cause: Missing added_to_cart jQuery event handler Solution: Use the AJAX tracking code provided in this guide

Variable Products Show Parent ID

Cause: Not capturing variation data Solution: Track variation selection with found_variation event

Next Steps