Google Analytics Event Tracking | OpsBlu Docs

Google Analytics Event Tracking

How to implement custom GA4 event tracking on OpenCart. Covers recommended events, custom event parameters, ecommerce data layer events, and DebugView.

Overview

Event tracking in GA4 captures user interactions beyond pageviews, including:

  • Button clicks (Add to Cart, Wishlist, Compare)
  • Form submissions (Newsletter signup, Contact forms)
  • Downloads and file interactions
  • Video plays and engagement
  • Custom user actions

Event Tracking Methods

Method 1: Extension-Based Events

Most premium GA4 extensions automatically track common events:

Auto-Tracked Events (Typical Extensions)

  • add_to_cart - Product added to cart
  • remove_from_cart - Product removed from cart
  • view_item - Product detail view
  • add_to_wishlist - Product added to wishlist
  • begin_checkout - Checkout process started
  • add_payment_info - Payment method selected
  • add_shipping_info - Shipping method selected
  • purchase - Order completed
  • search - Site search performed
  • select_item - Product clicked from listing

Configuration:

Admin Panel > Extensions > Extensions > Analytics > [Your GA4 Extension] > Edit

Enable desired auto-tracking features and save.

Method 2: Custom JavaScript Events

For tracking custom interactions not covered by extensions:

1. Add to Cart Button Tracking

Create a new JavaScript file or add to existing theme JS:

File: catalog/view/theme/[your-theme]/template/product/product.twig

Add before the closing </body> tag or in a separate JS file:

<script>
// Track Add to Cart button clicks
$(document).on('click', '#button-cart', function() {
    // Get product data from page
    var productName = $('h1').first().text().trim();
    var productId = $('input[name="product_id"]').val();
    var quantity = $('input[name="quantity"]').val();
    var price = $('.price-new').text() || $('.price').text();

    // Remove currency symbols and convert to number
    var priceValue = parseFloat(price.replace(/[^0-9.]/g, ''));

    // Send event to GA4
    gtag('event', 'add_to_cart', {
        'currency': 'USD',
        'value': priceValue * quantity,
        'items': [{
            'item_id': productId,
            'item_name': productName,
            'quantity': quantity,
            'price': priceValue
        }]
    });
});
</script>

2. Newsletter Subscription Tracking

File: catalog/view/theme/[your-theme]/template/common/footer.twig

<script>
// Track newsletter subscriptions
$(document).on('click', '#newsletter-subscribe', function() {
    var email = $('input[name="newsletter_email"]').val();

    gtag('event', 'newsletter_signup', {
        'method': 'footer_form',
        'email_provided': email ? 'yes' : 'no'
    });
});
</script>

3. Product Wishlist Tracking

<script>
// Track wishlist additions
$(document).on('click', '.wishlist-button, button[onclick*="wishlist.add"]', function() {
    var productId = $(this).data('product-id') ||
                    $(this).attr('onclick').match(/\d+/)[0];

    gtag('event', 'add_to_wishlist', {
        'items': [{
            'item_id': productId
        }]
    });
});
</script>

4. Product Compare Tracking

<script>
// Track product compare additions
$(document).on('click', '.compare-button, button[onclick*="compare.add"]', function() {
    var productId = $(this).data('product-id') ||
                    $(this).attr('onclick').match(/\d+/)[0];

    gtag('event', 'add_to_compare', {
        'items': [{
            'item_id': productId
        }]
    });
});
</script>

5. Contact Form Tracking

File: catalog/view/theme/[your-theme]/template/information/contact.twig

<script>
// Track contact form submissions
$(document).on('submit', '#contact-form', function() {
    gtag('event', 'contact_form_submit', {
        'form_type': 'contact',
        'form_location': 'contact_page'
    });
});
</script>

Method 3: Controller-Based Event Tracking

For server-side event tracking or when you need access to PHP data:

1. Create Custom Controller Extension

File: catalog/controller/extension/analytics/ga4_events.php

<?php
class ControllerExtensionAnalyticsGa4Events extends Controller {

    public function index() {
        // Only load if GA4 is enabled
        if ($this->config->get('analytics_ga4_status')) {
            $this->load->model('extension/analytics/ga4_events');

            // Get GA4 Measurement ID
            $measurement_id = $this->config->get('analytics_ga4_measurement_id');

            // Return tracking code with events
            return $this->model_extension_analytics_ga4_events->getEventScript($measurement_id);
        }

        return '';
    }

    public function trackCheckoutStep() {
        // Called via AJAX during checkout
        if ($this->request->server['REQUEST_METHOD'] == 'POST') {
            $step = isset($this->request->post['step']) ? $this->request->post['step'] : '';

            $event_data = array(
                'event' => 'checkout_progress',
                'checkout_step' => $step,
                'checkout_option' => $this->getCheckoutOption($step)
            );

            $json['success'] = true;
            $json['event_data'] = $event_data;

            $this->response->addHeader('Content-Type: application/json');
            $this->response->setOutput(json_encode($json));
        }
    }

    private function getCheckoutOption($step) {
        $options = array(
            'payment_address' => 'Billing Address',
            'shipping_address' => 'Shipping Address',
            'shipping_method' => 'Shipping Method',
            'payment_method' => 'Payment Method',
            'confirm' => 'Order Confirmation'
        );

        return isset($options[$step]) ? $options[$step] : '';
    }
}

2. Create Model for Event Data

File: catalog/model/extension/analytics/ga4_events.php

<?php
class ModelExtensionAnalyticsGa4Events extends Model {

    public function getEventScript($measurement_id) {
        $data = array();
        $data['measurement_id'] = $measurement_id;

        // Get cart data for events
        $data['cart_items'] = $this->getCartItems();

        return $this->load->view('extension/analytics/ga4_events', $data);
    }

    private function getCartItems() {
        $items = array();

        $products = $this->cart->getProducts();

        foreach ($products as $product) {
            $items[] = array(
                'item_id' => $product['product_id'],
                'item_name' => $product['name'],
                'price' => $this->currency->format($product['price'], $this->session->data['currency'], '', false),
                'quantity' => $product['quantity']
            );
        }

        return $items;
    }

    public function getProductData($product_id) {
        $this->load->model('catalog/product');

        $product = $this->model_catalog_product->getProduct($product_id);

        if ($product) {
            return array(
                'item_id' => $product['product_id'],
                'item_name' => $product['name'],
                'item_category' => $this->getProductCategory($product_id),
                'price' => $this->currency->format($product['price'], $this->session->data['currency'], '', false)
            );
        }

        return array();
    }

    private function getProductCategory($product_id) {
        $this->load->model('catalog/product');

        $categories = $this->model_catalog_product->getCategories($product_id);

        if ($categories) {
            $this->load->model('catalog/category');
            $category = $this->model_catalog_category->getCategory($categories[0]['category_id']);
            return $category ? $category['name'] : '';
        }

        return '';
    }
}

Method 4: OCMOD for Event Injection

Create an OCMOD to automatically inject event tracking across your store:

File: ga4-events.ocmod.xml

<?xml version="1.0" encoding="utf-8"?>
<modification>
    <name>GA4 Event Tracking</name>
    <code>ga4_event_tracking</code>
    <version>1.0</version>
    <author>Your Name</author>

    <!-- Add to Cart Event -->
    <file path="catalog/view/theme/*/template/product/product.twig">
        <operation>
            <search><![CDATA[<button type="button" id="button-cart"]]></search>
            <add position="before"><![CDATA[
<script>
$(document).ready(function() {
    $('#button-cart').on('click', function() {
        gtag('event', 'add_to_cart', {
            'currency': '{{ currency_code }}',
            'value': {{ product_price }},
            'items': [{
                'item_id': '{{ product_id }}',
                'item_name': '{{ product_name }}',
                'price': {{ product_price }}
            }]
        });
    });
});
</script>
            ]]></add>
        </operation>
    </file>

    <!-- Search Event -->
    <file path="catalog/view/theme/*/template/common/search.twig">
        <operation>
            <search><![CDATA[<button type="submit"]]></search>
            <add position="before"><![CDATA[
<script>
$(document).ready(function() {
    $('#search input[name="search"]').closest('form').on('submit', function() {
        var searchTerm = $(this).find('input[name="search"]').val();
        gtag('event', 'search', {
            'search_term': searchTerm
        });
    });
});
</script>
            ]]></add>
        </operation>
    </file>
</modification>

Install OCMOD:

Admin Panel > Extensions > Installer > Upload
Admin Panel > Extensions > Modifications > Refresh

Event Data Layer Integration

For advanced implementations, create a data layer that feeds GA4:

File: catalog/view/theme/[your-theme]/template/common/header.twig

Add after opening <body> tag:

<script>
window.dataLayer = window.dataLayer || [];

{% if page_type == 'product' %}
dataLayer.push({
    'event': 'view_item',
    'ecommerce': {
        'items': [{
            'item_id': '{{ product_id }}',
            'item_name': '{{ product_name }}',
            'item_category': '{{ product_category }}',
            'price': {{ product_price }},
            'currency': '{{ currency_code }}'
        }]
    }
});
{% endif %}

{% if page_type == 'category' %}
dataLayer.push({
    'event': 'view_item_list',
    'ecommerce': {
        'items': [
            {% for product in products %}
            {
                'item_id': '{{ product.product_id }}',
                'item_name': '{{ product.name }}',
                'price': {{ product.price }},
                'index': {{ loop.index }}
            }{% if not loop.last %},{% endif %}
            {% endfor %}
        ]
    }
});
{% endif %}
</script>

Custom Event Parameters

User Properties

Track user-specific properties:

gtag('set', 'user_properties', {
    'customer_type': 'returning',  // or 'new'
    'customer_group': 'wholesale', // or 'retail'
    'customer_lifetime_value': 1500.00
});

Enhanced Event Data

Add rich context to events:

gtag('event', 'view_item', {
    'currency': 'USD',
    'value': 29.99,
    'items': [{
        'item_id': '12345',
        'item_name': 'Product Name',
        'item_category': 'Category',
        'item_category2': 'Subcategory',
        'item_variant': 'Blue',
        'item_brand': 'Brand Name',
        'price': 29.99,
        'quantity': 1
    }],
    // Custom parameters
    'stock_level': 'in_stock',
    'product_rating': 4.5,
    'review_count': 87
});

Testing Events

Using GA4 DebugView

  1. Enable Debug Mode

Add to your page:

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

Or use Chrome extension: Google Analytics Debugger

  1. View Events in GA4
    • Go to GA4 property
    • Navigate to Configure > DebugView
    • Interact with your store in another tab
    • Watch events appear in real-time

Browser Console Testing

Test events directly in browser console:

// Test add_to_cart event
gtag('event', 'add_to_cart', {
    'currency': 'USD',
    'value': 29.99,
    'items': [{
        'item_id': 'TEST123',
        'item_name': 'Test Product',
        'price': 29.99
    }]
});

Network Tab Verification

  1. Open Developer Tools (F12)
  2. Go to Network tab
  3. Filter by "collect"
  4. Trigger an event (e.g., add to cart)
  5. Click the request to /g/collect
  6. Verify event parameters in Payload tab

Common Event Issues

Events Not Firing

Symptoms: Events don't appear in GA4 DebugView

Solutions:

  1. Check GA4 code is loaded:

    console.log(typeof gtag); // Should output "function"
    
  2. Verify Measurement ID is correct

  3. Check for JavaScript errors in console

  4. Ensure event is triggered (add console.log before gtag call)

Duplicate Events

Symptoms: Same event fires multiple times

Solutions:

  1. Use event delegation instead of multiple bindings
  2. Add .off() before .on() to prevent double-binding:
    $(document).off('click', '#button-cart').on('click', '#button-cart', function() {
        // Event code
    });
    
  3. Check for multiple GA4 extensions enabled

Missing Event Parameters

Symptoms: Events fire but lack required parameters

Solutions:

  1. Verify data availability:
    console.log('Product ID:', productId);
    console.log('Price:', priceValue);
    
  2. Check Twig variable output
  3. Ensure proper data type (number vs string)

Next Steps

Additional Resources