GA4 Event Tracking on 3dcart (Shift4Shop) | OpsBlu Docs

GA4 Event Tracking on 3dcart (Shift4Shop)

Custom event tracking implementation for GA4 on 3dcart/Shift4Shop including user interactions, form submissions, and custom events.

Implement custom GA4 event tracking on your 3dcart/Shift4Shop store to capture user interactions beyond standard page views and ecommerce events.

Event Tracking Overview

GA4 uses event-based tracking for all interactions. This guide covers custom events specific to 3dcart/Shift4Shop stores.

Standard GA4 Events

These events are automatically captured by GA4's Enhanced Measurement:

  • page_view - Page views
  • scroll - 90% scroll depth
  • click - Outbound link clicks
  • view_search_results - Site search (if configured)
  • file_download - File downloads

Custom Events for Ecommerce

For ecommerce-specific events, see the GA4 Ecommerce Tracking Guide.

Implementation Methods

Method 1: Direct gtag.js Implementation

Add events directly in Global Footer or page templates.

Method 2: Google Tag Manager

Use GTM for centralized event management (recommended). See GTM Setup Guide.

Common Custom Events for 3dcart Stores

Newsletter Signup

Track when customers subscribe to your newsletter.

Add to Global Footer:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Find newsletter form (adjust selector for your theme)
    var newsletterForm = document.querySelector('form[action*="newsletter"]');

    if (newsletterForm) {
      newsletterForm.addEventListener('submit', function(e) {
        gtag('event', 'newsletter_signup', {
          'event_category': 'engagement',
          'event_label': 'Newsletter Form',
          'method': 'email_form'
        });
      });
    }
  });
</script>

GTM Implementation:

  1. Create Trigger:

    • Type: Form Submission
    • Wait for Tags: Enabled (2000ms)
    • Enable when Form URL contains: newsletter
  2. Create GA4 Event Tag:

    • Event Name: newsletter_signup
    • Parameters:
      • method: email_form
    • Trigger: Newsletter Form Submit

Account Creation

Track new customer registrations.

Direct Implementation:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Track account creation on registration success page
    if (window.location.pathname.indexOf('/customer_register.asp') !== -1 &&
        window.location.search.indexOf('success=true') !== -1) {

      gtag('event', 'sign_up', {
        'method': 'email',
        'event_category': 'engagement'
      });
    }
  });
</script>

GTM Implementation:

  1. Create Variable:

    • Type: URL
    • Component Type: Query
    • Query Key: success
    • Name: URL - Query - Success
  2. Create Trigger:

    • Type: Page View
    • Fire when:
      • Page Path contains /customer_register.asp
      • AND \{\{URL - Query - Success\}\} equals true
  3. Create GA4 Event Tag:

    • Event Name: sign_up
    • Parameters:
      • method: email

Wishlist Interactions

Track when customers add products to wishlist.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Find wishlist buttons (adjust selector for your theme)
    var wishlistButtons = document.querySelectorAll('.wishlist-btn, [data-wishlist]');

    wishlistButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        var productId = button.getAttribute('data-product-id') || '';
        var productName = button.getAttribute('data-product-name') || '';

        gtag('event', 'add_to_wishlist', {
          'event_category': 'ecommerce',
          'product_id': productId,
          'product_name': productName
        });
      });
    });
  });
</script>

Product Review Submission

Track when customers submit product reviews.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var reviewForm = document.querySelector('form[action*="review"]');

    if (reviewForm) {
      reviewForm.addEventListener('submit', function() {
        var productId = '[productid]'; // Use 3dcart template variable
        var rating = reviewForm.querySelector('input[name="rating"]');
        var ratingValue = rating ? rating.value : '';

        gtag('event', 'review_submit', {
          'event_category': 'engagement',
          'product_id': productId,
          'rating': ratingValue
        });
      });
    }
  });
</script>

Live Chat Engagement

Track when customers interact with live chat.

<script>
  // Example for common chat widgets (adjust for your specific widget)
  document.addEventListener('DOMContentLoaded', function() {
    // For most chat widgets, listen for click on chat button
    var chatButton = document.querySelector('.chat-button, #live-chat-button');

    if (chatButton) {
      chatButton.addEventListener('click', function() {
        gtag('event', 'chat_started', {
          'event_category': 'engagement',
          'event_label': 'Live Chat'
        });
      });
    }
  });
</script>

Coupon Code Application

Track when customers apply discount codes.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Track coupon application in cart/checkout
    var couponForm = document.querySelector('form[name="coupon"], .coupon-form');

    if (couponForm) {
      couponForm.addEventListener('submit', function() {
        var couponInput = couponForm.querySelector('input[name="coupon"], input[name="couponcode"]');
        var couponCode = couponInput ? couponInput.value : '';

        gtag('event', 'coupon_apply', {
          'event_category': 'ecommerce',
          'coupon_code': couponCode,
          'event_label': couponCode
        });
      });
    }
  });
</script>

Search Tracking

Track internal site search queries.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var searchForm = document.querySelector('form[action*="search"]');

    if (searchForm) {
      searchForm.addEventListener('submit', function() {
        var searchInput = searchForm.querySelector('input[name="query"], input[name="q"]');
        var searchTerm = searchInput ? searchInput.value : '';

        gtag('event', 'search', {
          'search_term': searchTerm,
          'event_category': 'engagement'
        });
      });
    }
  });
</script>

Product Comparison

Track when customers use product comparison features.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var compareButtons = document.querySelectorAll('.compare-btn, [data-compare]');

    compareButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        var productId = button.getAttribute('data-product-id') || '[productid]';

        gtag('event', 'add_to_compare', {
          'event_category': 'engagement',
          'product_id': productId
        });
      });
    });
  });
</script>

Shipping Calculator Usage

Track when customers check shipping rates.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var shippingCalc = document.querySelector('form[action*="shipping"], .shipping-calculator');

    if (shippingCalc) {
      shippingCalc.addEventListener('submit', function() {
        var zipInput = shippingCalc.querySelector('input[name="zip"]');
        var zipCode = zipInput ? zipInput.value : '';

        gtag('event', 'shipping_calculator', {
          'event_category': 'engagement',
          'event_label': 'Estimate Shipping',
          'zip_code': zipCode
        });
      });
    }
  });
</script>

Social Media Shares

Track when customers share products on social media.

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Track social share buttons
    var shareButtons = document.querySelectorAll('.social-share, [data-share]');

    shareButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        var network = button.getAttribute('data-network') ||
                     button.className.match(/(facebook|twitter|pinterest|instagram)/)?.[0] ||
                     'unknown';
        var productId = '[productid]';

        gtag('event', 'share', {
          'method': network,
          'content_type': 'product',
          'item_id': productId
        });
      });
    });
  });
</script>

File Downloads

Track product-related file downloads (specs, manuals, etc.).

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var downloadLinks = document.querySelectorAll('a[href$=".pdf"], a[href$=".zip"], a[download]');

    downloadLinks.forEach(function(link) {
      link.addEventListener('click', function() {
        var fileName = link.getAttribute('href').split('/').pop();
        var fileType = fileName.split('.').pop();

        gtag('event', 'file_download', {
          'file_name': fileName,
          'file_extension': fileType,
          'link_url': link.getAttribute('href')
        });
      });
    });
  });
</script>

Using 3dcart Template Variables in Events

Product Page Events

On product pages, use template variables for dynamic data:

<script>
  // Only execute on product pages
  if (window.location.pathname.indexOf('/product') !== -1 ||
      document.querySelector('.product-page, .product-details')) {

    // Track when customer views size guide
    var sizeGuideBtn = document.querySelector('.size-guide, [data-size-chart]');
    if (sizeGuideBtn) {
      sizeGuideBtn.addEventListener('click', function() {
        gtag('event', 'size_guide_view', {
          'event_category': 'engagement',
          'product_id': '[productid]',
          'product_name': '[productname]'
        });
      });
    }

    // Track video plays
    var productVideo = document.querySelector('.product-video, video');
    if (productVideo) {
      productVideo.addEventListener('play', function() {
        gtag('event', 'video_start', {
          'event_category': 'engagement',
          'product_id': '[productid]',
          'video_title': 'Product Video'
        });
      });
    }
  }
</script>

Category Page Events

<script>
  // Only on category pages
  if (window.location.pathname.indexOf('/category') !== -1) {

    // Track filter usage
    var filterOptions = document.querySelectorAll('.filter-option, [data-filter]');
    filterOptions.forEach(function(filter) {
      filter.addEventListener('click', function() {
        var filterType = filter.getAttribute('data-filter-type') || 'unknown';
        var filterValue = filter.getAttribute('data-filter-value') || filter.textContent;

        gtag('event', 'filter_apply', {
          'event_category': 'engagement',
          'filter_type': filterType,
          'filter_value': filterValue,
          'category_id': '[categoryid]'
        });
      });
    });

    // Track sort changes
    var sortSelect = document.querySelector('select[name="sort"], .sort-select');
    if (sortSelect) {
      sortSelect.addEventListener('change', function() {
        gtag('event', 'sort_change', {
          'event_category': 'engagement',
          'sort_by': this.value,
          'category_id': '[categoryid]'
        });
      });
    }
  }
</script>

GTM-Based Event Tracking

Setting Up Click Event Tracking

1. Enable Built-in Click Variables:

  • In GTM, go to Variables → Configure
  • Enable:
    • Click Element
    • Click Classes
    • Click ID
    • Click Text
    • Click URL

2. Create Click Trigger:

  • Type: All Elements
  • Fire when:
    • Click Classes contains add-to-wishlist
    • OR Click ID contains wishlist

3. Create GA4 Event Tag:

  • Event Name: add_to_wishlist
  • Parameters:
    • event_category: engagement
    • click_text: \{\{Click Text\}\}

Advanced: Custom JavaScript Variables

Create variables to extract 3dcart data:

Product ID from Data Attribute:

function() {
  var clickedElement = {{Click Element}};
  return clickedElement ? clickedElement.getAttribute('data-product-id') : '';
}

Cart Total:

function() {
  // Parse cart total from page (adjust selector for your theme)
  var cartTotal = document.querySelector('.cart-total, .total-amount');
  if (cartTotal) {
    var amount = cartTotal.textContent.replace(/[^0-9.]/g, '');
    return parseFloat(amount) || 0;
  }
  return 0;
}

Testing Event Tracking

Use GA4 DebugView

  1. Enable Debug Mode:

    • Add ?debug_mode=true to your URL
    • Or use browser extension
  2. View Events:

    • Go to GA4 → Admin → DebugView
    • Perform actions on your store
    • Verify events appear in DebugView

Use GTM Preview Mode

  1. Start Preview:

    • Click Preview in GTM
    • Enter your store URL
  2. Test Events:

    • Perform actions (clicks, form submits, etc.)
    • Verify triggers fire in Tag Assistant
    • Check that tags send data

Browser Console Testing

// Check if gtag is defined
console.log(typeof gtag);

// Monitor dataLayer pushes
console.log(window.dataLayer);

// Test event manually
gtag('event', 'test_event', {'test': 'value'});

Event Naming Best Practices

Follow GA4 Conventions

Recommended Events (use Google's standard names):

  • sign_up
  • login
  • search
  • share
  • add_to_wishlist

Custom Events (use snake_case):

  • size_guide_view
  • shipping_calculator
  • product_compare

Event Parameters

Standard Parameters:

  • event_category - Group similar events
  • event_label - Additional context
  • value - Numeric value (if applicable)

Custom Parameters:

  • Use descriptive names
  • Keep parameter names consistent
  • Avoid personally identifiable information (PII)

Common Issues and Solutions

Events Not Firing

Check:

  1. JavaScript console for errors
  2. Element selectors match your theme
  3. Events are on correct page types
  4. GA4 is properly initialized

Debug:

// Add console logging
gtag('event', 'test_event', {
  'event_callback': function() {
    console.log('Event sent successfully');
  }
});

Template Variables Not Working

Issue: Variables showing literal text like [productid]

Solution:

  • Only use template variables on appropriate pages
  • Verify variable syntax in 3dcart documentation
  • Use JavaScript fallbacks when possible

Duplicate Events

Cause: Multiple event listeners on same element

Fix:

// Remove existing listeners before adding new ones
var button = document.querySelector('.my-button');
var newButton = button.cloneNode(true);
button.parentNode.replaceChild(newButton, button);

// Now add listener to fresh element
newButton.addEventListener('click', function() {
  gtag('event', 'my_event');
});

Next Steps

Additional Resources