Meta Pixel Event Tracking on 3dcart (Shift4Shop) | OpsBlu Docs

Meta Pixel Event Tracking on 3dcart (Shift4Shop)

Complete Meta Pixel event implementation for 3dcart/Shift4Shop including standard events, custom events, and ecommerce tracking.

Implement comprehensive Meta Pixel event tracking on your 3dcart/Shift4Shop store to optimize Facebook and Instagram advertising campaigns.

Event Tracking Overview

Meta Pixel uses standard events to track customer actions. This guide covers implementation specific to 3dcart/Shift4Shop.

Standard Events for Ecommerce

Event Name Purpose 3dcart Page Priority
PageView Page visits All pages Required
ViewContent Product views Product pages High
AddToCart Cart additions All pages High
InitiateCheckout Checkout start Checkout High
Purchase Completed orders Order confirmation Required
Search Site search Search results Medium
AddToWishlist Wishlist add Product pages Low
Lead Contact form Contact page Medium

ViewContent Event

Track when customers view product details.

Product Page Implementation

Add to Global Footer with page detection:

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

    fbq('track', 'ViewContent', {
      content_ids: ['[productid]'],
      content_name: '[productname]',
      content_type: 'product',
      content_category: '[categoryname]',
      value: parseFloat('[productprice]'),
      currency: 'USD'
    });
  }
</script>

With Multiple Product IDs (Variants)

If tracking variants as separate products:

<script>
  if (window.location.pathname.indexOf('/product') !== -1) {
    var variantId = '[productid]'; // Main product ID
    var selectedOption = document.querySelector('select[name="options"]');
    var variantSku = selectedOption ? selectedOption.value : '';

    fbq('track', 'ViewContent', {
      content_ids: [variantId, variantSku].filter(Boolean),
      content_name: '[productname]',
      content_type: 'product',
      value: parseFloat('[productprice]'),
      currency: 'USD'
    });
  }
</script>

GTM Implementation

Create Variable: Product ID

function() {
  var productId = document.querySelector('[data-product-id]');
  return productId ? productId.getAttribute('data-product-id') : '';
}

Create Trigger:

  • Type: Page View
  • Fire on: Page Path contains /product

Create Tag:

  • Type: Custom HTML
  • Code:
<script>
  fbq('track', 'ViewContent', {
    content_ids: ['{{DL - Product ID}}'],
    content_type: 'product',
    value: {{DL - Product Price}},
    currency: 'USD'
  });
</script>

AddToCart Event

Track when items are added to the shopping cart.

Standard Add to Cart

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Find add to cart forms (adjust selector for your theme)
    var addToCartForms = document.querySelectorAll('form[action*="addtocart"], .add-to-cart-form');

    addToCartForms.forEach(function(form) {
      form.addEventListener('submit', function(e) {
        // Get quantity
        var quantityInput = form.querySelector('input[name="quantity"]');
        var quantity = quantityInput ? parseInt(quantityInput.value) : 1;

        // Get product price
        var productPrice = parseFloat('[productprice]');
        var totalValue = productPrice * quantity;

        // Fire AddToCart event
        fbq('track', 'AddToCart', {
          content_ids: ['[productid]'],
          content_name: '[productname]',
          content_type: 'product',
          value: totalValue,
          currency: 'USD'
        });
      });
    });
  });
</script>

AJAX Add to Cart

For themes using AJAX cart functionality:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Listen for AJAX add to cart
    var ajaxCartButtons = document.querySelectorAll('.ajax-add-to-cart, [data-ajax-cart]');

    ajaxCartButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        var productId = button.getAttribute('data-product-id') || '[productid]';
        var productName = button.getAttribute('data-product-name') || '[productname]';
        var productPrice = button.getAttribute('data-product-price') || '[productprice]';

        // Get quantity
        var qtyInput = button.closest('.product-item')?.querySelector('input[name="quantity"]');
        var quantity = qtyInput ? parseInt(qtyInput.value) : 1;

        fbq('track', 'AddToCart', {
          content_ids: [productId],
          content_name: productName,
          content_type: 'product',
          value: parseFloat(productPrice) * quantity,
          currency: 'USD'
        });
      });
    });
  });
</script>

Quick Add from Category Pages

Track quick add buttons on category/listing pages:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var quickAddButtons = document.querySelectorAll('.quick-add, [data-quick-add]');

    quickAddButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        var productBox = button.closest('.product-item, .product-box');
        var productId = productBox?.getAttribute('data-product-id');
        var productName = productBox?.querySelector('.product-name')?.textContent;
        var productPrice = productBox?.querySelector('.product-price')?.textContent;

        if (productId && productPrice) {
          fbq('track', 'AddToCart', {
            content_ids: [productId],
            content_name: productName?.trim() || '',
            content_type: 'product',
            value: parseFloat(productPrice.replace(/[^0-9.]/g, '')),
            currency: 'USD'
          });
        }
      });
    });
  });
</script>

InitiateCheckout Event

Track when customers begin the checkout process.

Checkout Page Load

<script>
  // Fire on checkout page load
  if (window.location.pathname.indexOf('/checkout') !== -1 ||
      window.location.pathname.indexOf('/onepage') !== -1) {

    // Get cart/order total
    var orderTotal = document.querySelector('.order-total, .total-amount, [data-total]');
    var total = orderTotal ? parseFloat(orderTotal.textContent.replace(/[^0-9.]/g, '')) : 0;

    // Get number of items
    var itemRows = document.querySelectorAll('.checkout-item, .order-item');
    var numItems = itemRows.length;

    fbq('track', 'InitiateCheckout', {
      content_type: 'product',
      value: total,
      currency: 'USD',
      num_items: numItems
    });
  }
</script>

Alternative: Checkout Button Click

Track when checkout button is clicked from cart page:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var checkoutButton = document.querySelector('.checkout-button, button[name="checkout"], a[href*="checkout"]');

    if (checkoutButton) {
      checkoutButton.addEventListener('click', function() {
        // Parse cart total from page
        var cartTotal = document.querySelector('.cart-total, .total-amount');
        var total = cartTotal ? parseFloat(cartTotal.textContent.replace(/[^0-9.]/g, '')) : 0;

        fbq('track', 'InitiateCheckout', {
          content_type: 'product',
          value: total,
          currency: 'USD'
        });
      });
    }
  });
</script>

Purchase Event

Track completed purchases on order confirmation page.

Order Confirmation Implementation

<script>
  // Only fire on order confirmation/receipt page
  if (window.location.pathname.indexOf('/receipt') !== -1 ||
      window.location.pathname.indexOf('/thankyou') !== -1 ||
      document.querySelector('.order-confirmation, .receipt-page')) {

    var orderId = '[invoicenumber]';

    // Prevent duplicate tracking on page refresh
    if (!sessionStorage.getItem('fb_purchase_' + orderId)) {

      fbq('track', 'Purchase', {
        content_type: 'product',
        value: parseFloat('[invoicetotal]'),
        currency: 'USD',
        transaction_id: orderId
      });

      // Mark as tracked
      sessionStorage.setItem('fb_purchase_' + orderId, 'true');
    }
  }
</script>

Purchase with Product Details

Include product information in purchase event:

<script>
  if (window.location.pathname.indexOf('/receipt') !== -1) {
    var orderId = '[invoicenumber]';

    if (!sessionStorage.getItem('fb_purchase_' + orderId)) {

      // Parse product IDs from order
      var productIds = [];
      var orderItems = document.querySelectorAll('.order-item, .receipt-item');

      orderItems.forEach(function(item) {
        var sku = item.querySelector('.sku, .product-sku')?.textContent;
        if (sku) productIds.push(sku.trim());
      });

      fbq('track', 'Purchase', {
        content_ids: productIds,
        content_type: 'product',
        value: parseFloat('[invoicetotal]'),
        currency: 'USD',
        transaction_id: orderId,
        num_items: productIds.length
      });

      sessionStorage.setItem('fb_purchase_' + orderId, 'true');
    }
  }
</script>

Search Event

Track site search usage.

Search Results Page

<script>
  // Detect search results page
  if (window.location.pathname.indexOf('/search') !== -1 ||
      window.location.search.indexOf('search') !== -1) {

    // Get search query from URL
    var urlParams = new URLSearchParams(window.location.search);
    var searchQuery = urlParams.get('q') || urlParams.get('query') || '';

    if (searchQuery) {
      fbq('track', 'Search', {
        search_string: searchQuery,
        content_category: 'Product Search'
      });
    }
  }
</script>

Search Form Submission

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

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

        if (searchTerm) {
          fbq('track', 'Search', {
            search_string: searchTerm
          });
        }
      });
    }
  });
</script>

AddToWishlist Event

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, .add-to-wishlist, [data-wishlist]');

    wishlistButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        var productId = button.getAttribute('data-product-id') || '[productid]';
        var productName = button.getAttribute('data-product-name') || '[productname]';
        var productPrice = button.getAttribute('data-product-price') || '[productprice]';

        fbq('track', 'AddToWishlist', {
          content_ids: [productId],
          content_name: productName,
          content_type: 'product',
          value: parseFloat(productPrice),
          currency: 'USD'
        });
      });
    });
  });
</script>

Lead Event

Track lead generation (contact forms, quote requests, etc.).

Contact Form Submission

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

    if (contactForm) {
      contactForm.addEventListener('submit', function() {
        fbq('track', 'Lead', {
          content_category: 'Contact Form',
          content_name: 'Contact Us Form Submission'
        });
      });
    }
  });
</script>

Newsletter Signup

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

    if (newsletterForm) {
      newsletterForm.addEventListener('submit', function() {
        fbq('track', 'Lead', {
          content_category: 'Newsletter',
          content_name: 'Newsletter Signup'
        });
      });
    }
  });
</script>

Custom Events

Create custom events for unique business needs.

Size Guide View

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var sizeGuideBtn = document.querySelector('.size-guide, [data-size-chart]');

    if (sizeGuideBtn) {
      sizeGuideBtn.addEventListener('click', function() {
        fbq('trackCustom', 'ViewSizeGuide', {
          content_name: '[productname]',
          product_id: '[productid]'
        });
      });
    }
  });
</script>

Live Chat Start

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var chatButton = document.querySelector('.chat-button, #live-chat');

    if (chatButton) {
      chatButton.addEventListener('click', function() {
        fbq('trackCustom', 'ChatStarted', {
          content_category: 'Customer Support'
        });
      });
    }
  });
</script>

Coupon Application

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

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

        fbq('trackCustom', 'CouponApplied', {
          coupon_code: couponCode
        });
      });
    }
  });
</script>

Using GTM for Event Tracking

Create Event Tags in GTM

Example: AddToCart via GTM

  1. Create Data Layer Push (in Global Footer):
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var addToCartForms = document.querySelectorAll('form[action*="addtocart"]');

    addToCartForms.forEach(function(form) {
      form.addEventListener('submit', function() {
        window.dataLayer = window.dataLayer || [];
        dataLayer.push({
          'event': 'addToCart',
          'productId': '[productid]',
          'productName': '[productname]',
          'productPrice': parseFloat('[productprice]')
        });
      });
    });
  });
</script>
  1. Create GTM Variables:
  • DL - Product ID → Data Layer Variable → productId
  • DL - Product Name → Data Layer Variable → productName
  • DL - Product Price → Data Layer Variable → productPrice
  1. Create GTM Trigger:
  • Type: Custom Event
  • Event name: addToCart
  1. Create GTM Tag:
  • Type: Custom HTML
  • HTML:
<script>
  fbq('track', 'AddToCart', {
    content_ids: ['{{DL - Product ID}}'],
    content_name: '{{DL - Product Name}}',
    content_type: 'product',
    value: {{DL - Product Price}},
    currency: 'USD'
  });
</script>
  • Trigger: Custom Event - addToCart

Testing Event Tracking

Meta Pixel Helper

  1. Install Extension:

  2. Test Events:

    • Visit different pages
    • Click Pixel Helper icon
    • See events fired in real-time
    • Verify event parameters

Meta Events Manager - Test Events

  1. Go to Events Manager:

  2. Test Events Tab:

    • Enter your store URL
    • Perform actions on your store
    • See events appear in Test Events
    • Verify parameters are correct

Browser Console Testing

// Monitor fbq calls
const originalFbq = window.fbq;
window.fbq = function() {
  console.log('Meta Pixel Event:', arguments);
  originalFbq.apply(this, arguments);
};

// Test event manually
fbq('track', 'AddToCart', {
  content_ids: ['TEST123'],
  value: 99.99,
  currency: 'USD'
});

GTM Preview Mode

  1. Enable Preview in GTM
  2. Connect to your store
  3. Perform actions (view product, add to cart, etc.)
  4. Verify tags fire in Tag Assistant
  5. Check event parameters in Variables tab

Event Parameter Best Practices

Required Parameters

Minimum parameters for each event:

  • ViewContent: content_ids, content_type, value, currency
  • AddToCart: content_ids, content_type, value, currency
  • InitiateCheckout: content_type, value, currency
  • Purchase: value, currency, transaction_id
  • content_name - Product name
  • content_category - Product category
  • num_items - Number of items
  • contents - Array of product objects (for multiple items)

Parameter Format

Correct:

{
  content_ids: ['123', '456'],
  value: 99.99,
  currency: 'USD'
}

Incorrect:

{
  content_ids: 123, // Should be array
  value: '$99.99', // Should be number
  currency: 'usd' // Should be uppercase
}

Common Issues and Solutions

Events Not Showing in Events Manager

Check:

  • Pixel Helper shows green (pixel firing)
  • Events appear in Test Events
  • Wait 20 minutes for events to process
  • Check date range filter in Events Manager

Duplicate Events

Causes:

  • Multiple pixel implementations
  • Event firing multiple times
  • Both GTM and direct implementation

Fix:

  • Use only one implementation method
  • Add deduplication logic
  • Remove duplicate code

Template Variables Not Populating

Issue: Parameters show [productid] instead of actual ID

Fix:

// Only use variables on appropriate pages
if (window.location.pathname.indexOf('/product') !== -1) {
  // Use [productid] here
}

Value Parameter Showing NaN

Cause: Non-numeric value passed to parseFloat

Fix:

var price = '[productprice]';
var value = parseFloat(price.replace(/[^0-9.]/g, '')) || 0;

Next Steps

Additional Resources