This guide covers WooCommerce-specific methods for implementing Google Analytics 4 (GA4) with full eCommerce tracking capabilities.
Prerequisites
Before installing GA4 on WooCommerce:
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)
Choose Your Implementation Method based on:
- Technical expertise level
- Need for custom product tracking
- Performance requirements
- Existing WooCommerce setup
Method 1: MonsterInsights (Recommended for Beginners)
Best for: Non-technical users, automatic eCommerce tracking, quick setup
Why MonsterInsights for WooCommerce?
- Automatic WooCommerce integration
- Enhanced eCommerce tracking out-of-the-box
- Product performance reports in WordPress dashboard
- No code required
Installation Steps
Install MonsterInsights
- Navigate to Plugins → Add New
- Search for "MonsterInsights"
- Install and activate (Pro version required for eCommerce)
Connect to Google Analytics
- Click MonsterInsights → Settings
- Click Connect with Google
- Authenticate and select your GA4 property
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
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)Verify Installation
- Visit your WooCommerce store
- Add a product to cart
- Check Google Analytics → Reports → Realtime → Events
- Confirm
add_to_cartevent 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
Install the Plugin
- Go to Plugins → Add New
- Search "WooCommerce Google Analytics Integration"
- Install and activate (free)
Configure Settings
- Navigate to WooCommerce → Settings → Integration → Google Analytics
- Enter your Measurement ID (
G-XXXXXXXXXX)
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 IDAJAX 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:
- Install GTM container code
- Configure WooCommerce data layer
- Add GA4 Configuration Tag
- 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:
- Browse products → Check
view_item_listevent - View product → Check
view_itemevent - Add to cart → Check
add_to_cartevent - View cart → Check
view_cartevent - Begin checkout → Check
begin_checkoutevent - Complete purchase → Check
purchaseevent
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
- Configure WooCommerce Event Tracking for custom events
- Set Up Enhanced Ecommerce Tracking for complete product analytics
- Debug Tracking Issues
Related Resources
- GA4 Fundamentals - Universal GA4 concepts
- Google Tag Manager Setup - Alternative implementation
- WooCommerce Performance - Optimize tracking impact