Google Analytics 4 Event Tracking for CS-Cart | OpsBlu Docs

Google Analytics 4 Event Tracking for CS-Cart

Implement custom event tracking in CS-Cart to monitor user interactions, product engagement, and customer behavior

This guide covers implementing custom GA4 events in CS-Cart to track user interactions beyond basic page views and ecommerce transactions.

Overview

GA4 events help you understand how customers interact with your CS-Cart store. This guide focuses on non-ecommerce events (see Ecommerce Tracking for purchase tracking).

Automatic vs. Custom Events

Automatically Collected Events

GA4 automatically tracks these events with Enhanced Measurement:

  • page_view - Page views
  • scroll - Users who scroll to bottom (90%)
  • click - Outbound link clicks
  • view_search_results - Site search usage
  • video_start, video_progress, video_complete - Video engagement
  • file_download - File downloads

Google recommends these events for ecommerce sites:

  • search - Product/site search
  • view_item_list - Product list views
  • select_item - Product selection from list
  • view_item - Product detail views
  • add_to_wishlist - Wishlist additions
  • add_to_cart - Cart additions (covered in ecommerce guide)
  • begin_checkout - Checkout start (covered in ecommerce guide)
  • purchase - Transaction completion (covered in ecommerce guide)

Custom Events

Create custom events for CS-Cart-specific interactions:

  • Account registration
  • Newsletter signup
  • Product comparisons
  • Wishlist interactions
  • Customer reviews
  • Quick view usage
  • Filter applications
  • Vendor page views (Multi-Vendor)

Implementation Methods

Method 1: Direct Event Implementation

Add event tracking directly in CS-Cart templates or JavaScript.

Basic Event Syntax

gtag('event', 'event_name', {
  'parameter1': 'value1',
  'parameter2': 'value2'
});

Method 2: Using Google Tag Manager

For easier management and testing, implement events via GTM (see GTM Setup).

Common CS-Cart Events

Site Search Tracking

Track when customers search your catalog:

In search results template (design/themes/[theme]/templates/blocks/product_filters/search.tpl):

{literal}
<script>
  // Track search event
  {/literal}
  {if $search.q}
  gtag('event', 'search', {
    'search_term': '{$search.q|escape:javascript}',
    'search_results': {$products|count}
  });
  {/if}
  {literal}
</script>
{/literal}

Newsletter Signup

Track newsletter subscriptions:

// Add to newsletter subscription handler
document.addEventListener('DOMContentLoaded', function() {
  const newsletterForm = document.querySelector('#subscribe_form');

  if (newsletterForm) {
    newsletterForm.addEventListener('submit', function(e) {
      gtag('event', 'newsletter_signup', {
        'method': 'footer_form'
      });
    });
  }
});

Product Wishlist

Track wishlist additions:

// Hook into CS-Cart wishlist function
$(document).on('click', '.cm-add-to-wish-list', function() {
  const productId = $(this).data('product-id');
  const productName = $(this).data('product-name') || 'Unknown Product';

  gtag('event', 'add_to_wishlist', {
    'currency': 'USD', // Use your store currency
    'value': parseFloat($(this).data('product-price')) || 0,
    'items': [{
      'item_id': productId,
      'item_name': productName
    }]
  });
});

Product Compare

Track product comparison usage:

// Add to compare tracking
$(document).on('click', '.cm-add-to-comparison-list', function() {
  const productId = $(this).data('product-id');
  const productName = $(this).data('product-name');

  gtag('event', 'add_to_compare', {
    'items': [{
      'item_id': productId,
      'item_name': productName
    }]
  });
});

Customer Reviews

Track when customers submit reviews:

// In review form template
document.querySelector('.cm-submit-review')?.addEventListener('click', function() {
  const productId = this.dataset.productId;
  const rating = document.querySelector('input[name="rating"]:checked')?.value;

  gtag('event', 'submit_review', {
    'item_id': productId,
    'rating': rating,
    'review_type': 'product_review'
  });
});

Quick View

Track product quick view usage:

// Hook into quick view modal
$(document).on('click', '.cm-dialog-opener.product-quick-view', function() {
  const productId = $(this).data('product-id');
  const productName = $(this).data('product-name');

  gtag('event', 'quick_view', {
    'item_id': productId,
    'item_name': productName,
    'engagement_type': 'quick_view'
  });
});

User Registration

Track new account creation:

In registration success template (design/themes/[theme]/templates/views/checkout/components/profile_account.tpl):

{if $user_data.user_id && $runtime.controller == 'profiles' && $runtime.mode == 'add'}
{literal}
<script>
  gtag('event', 'sign_up', {
    'method': 'website_registration'
  });
</script>
{/literal}
{/if}

Login Tracking

Track customer logins:

// After successful login
gtag('event', 'login', {
  'method': 'email'
});

Product Filter Usage

Track catalog filter applications:

// Hook into filter application
$(document).on('click', '.cm-submit-filter', function() {
  const filters = {};
  $('.ty-product-filters__group input:checked').each(function() {
    const filterName = $(this).attr('name');
    filters[filterName] = $(this).val();
  });

  gtag('event', 'apply_filter', {
    'filter_type': 'product_catalog',
    'filters_applied': Object.keys(filters).length
  });
});

Video Interaction

If you have product videos:

// YouTube player events
function onPlayerStateChange(event) {
  const videoTitle = event.target.getVideoData().title;

  if (event.data == YT.PlayerState.PLAYING) {
    gtag('event', 'video_start', {
      'video_title': videoTitle,
      'video_provider': 'youtube'
    });
  }
}

Download Tracking

Track catalog/brochure downloads:

document.querySelectorAll('a[href$=".pdf"]').forEach(function(link) {
  link.addEventListener('click', function(e) {
    const fileName = this.getAttribute('href').split('/').pop();

    gtag('event', 'file_download', {
      'file_name': fileName,
      'file_extension': 'pdf',
      'link_url': this.href
    });
  });
});

Multi-Vendor Events

For CS-Cart Multi-Vendor marketplace:

Vendor Page Views

// On vendor storefront page
gtag('event', 'view_vendor', {
  'vendor_id': '{$vendor_info.company_id}',
  'vendor_name': '{$vendor_info.company|escape:javascript}'
});

Contact Vendor

// When customer contacts vendor
gtag('event', 'contact_vendor', {
  'vendor_id': vendorId,
  'contact_method': 'contact_form'
});

Advanced Event Tracking

Scroll Depth Tracking

Track how far users scroll on product pages:

let scrollTracked = {
  '25': false,
  '50': false,
  '75': false,
  '100': false
};

window.addEventListener('scroll', function() {
  const scrollPercent = Math.round((window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100);

  Object.keys(scrollTracked).forEach(function(threshold) {
    if (scrollPercent >= threshold && !scrollTracked[threshold]) {
      scrollTracked[threshold] = true;

      gtag('event', 'scroll_depth', {
        'percent_scrolled': threshold,
        'page_type': 'product_page'
      });
    }
  });
});

Time on Page

Track engaged users:

let timeOnPage = 0;
let trackingInterval = setInterval(function() {
  timeOnPage += 10;

  // Track at 30 seconds, 60 seconds, etc.
  if (timeOnPage === 30 || timeOnPage === 60 || timeOnPage === 120) {
    gtag('event', 'user_engagement', {
      'engagement_time_msec': timeOnPage * 1000,
      'page_location': window.location.href
    });
  }
}, 10000); // Every 10 seconds

// Clear on page unload
window.addEventListener('beforeunload', function() {
  clearInterval(trackingInterval);
});

Error Tracking

Track JavaScript errors:

window.addEventListener('error', function(e) {
  gtag('event', 'exception', {
    'description': e.message,
    'fatal': false
  });
});

AJAX Error Tracking

Track AJAX failures in CS-Cart:

$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
  gtag('event', 'ajax_error', {
    'error_message': thrownError,
    'ajax_url': settings.url,
    'fatal': false
  });
});

Implementing Events with CS-Cart Hooks

Use CS-Cart's hook system for clean integration:

Create Custom Add-on

File: app/addons/custom_ga4_events/init.php

<?php

if (!defined('BOOTSTRAP')) { die('Access denied'); }

// Hook into product view
function fn_custom_ga4_events_get_product_data_post(&$product_id, &$field_list, &$join, &$auth, &$lang_code, &$condition, &$product_data) {
    // Add GA4 event tracking data
    $product_data['ga4_event_ready'] = true;
}

// Hook into cart operations
function fn_custom_ga4_events_add_to_cart_post(&$cart, &$product_id, &$product_data) {
    // Trigger add_to_cart event (via JavaScript)
}

Template hook (design/themes/[theme]/templates/addons/custom_ga4_events/hooks/index/scripts.post.tpl):

{if $product.ga4_event_ready}
{literal}
<script>
  // GA4 event tracking based on hook data
  gtag('event', 'view_item', {
    'items': [{
      'item_id': '{/literal}{$product.product_id}{literal}',
      'item_name': '{/literal}{$product.product|escape:javascript}{literal}'
    }]
  });
</script>
{/literal}
{/if}

Testing and Validation

Using GA4 DebugView

  1. Install Google Analytics Debugger Chrome extension
  2. Enable the extension
  3. In GA4, go to Admin → DebugView
  4. Trigger events on your CS-Cart store
  5. Verify events appear in DebugView with correct parameters

Using Browser Console

// Enable GA4 debug mode
gtag('config', 'G-XXXXXXXXXX', {
  'debug_mode': true
});

// Check dataLayer
console.log(window.dataLayer);

Using Tag Assistant

  1. Install Tag Assistant
  2. Connect to your site
  3. Trigger events
  4. Verify events are captured correctly

Best Practices

1. Event Naming Conventions

Use Google's recommended event names when possible:

  • Use lowercase and underscores: add_to_cart, not addToCart
  • Be descriptive but concise
  • Follow GA4 naming conventions

2. Event Parameters

  • Include relevant context with each event
  • Use consistent parameter names
  • Don't exceed 25 parameters per event
  • Parameter names: max 40 characters
  • Parameter values: max 100 characters

3. Data Quality

  • Validate data before sending events
  • Handle null/undefined values
  • Ensure product IDs are consistent across events
  • Use try/catch for error handling

4. Performance

  • Don't block page load with event tracking
  • Use event delegation for dynamic elements
  • Avoid excessive event firing
  • Debounce rapid events (scroll, resize)

5. Privacy Compliance

  • Don't send personally identifiable information (PII)
  • Respect cookie consent settings
  • Anonymize sensitive data
  • Follow GDPR/privacy regulations

Common Issues

Events Not Firing

Check:

  1. GA4 is properly installed
  2. Measurement ID is correct
  3. No JavaScript errors in console
  4. Event syntax is correct
  5. Elements exist in DOM

Duplicate Events

Solutions:

  1. Check for multiple event listeners
  2. Verify events aren't triggered in multiple places
  3. Use event delegation properly
  4. Remove conflicting plugins/add-ons

Missing Event Parameters

Solutions:

  1. Verify data is available when event fires
  2. Check variable scope
  3. Use default values for optional parameters
  4. Log events to console for debugging

Next Steps

Additional Resources