Meta Pixel Event Tracking on Ecwid | OpsBlu Docs

Meta Pixel Event Tracking on Ecwid

Complete guide to tracking Meta Pixel events on Ecwid including standard events, custom events, and the Ecwid JavaScript API.

Comprehensive guide to implementing Meta Pixel (Facebook Pixel) event tracking on Ecwid stores using the Ecwid JavaScript API.

Meta Pixel Standard Events

Meta provides standard events optimized for advertising and conversion tracking.

Standard Events for Ecommerce

Event When to Fire Required Parameters
ViewContent Product page viewed content_ids, content_type, value, currency
Search Search performed search_string
AddToCart Item added to cart content_ids, content_type, value, currency
AddToWishlist Item added to wishlist content_ids, content_type, value, currency
InitiateCheckout Checkout started content_ids, contents, value, currency, num_items
AddPaymentInfo Payment info added content_ids, contents, value, currency
Purchase Order completed content_ids, contents, value, currency, num_items
Lead Lead form submitted None required
CompleteRegistration Account created None required

Event Data Structure

All events follow this structure:

fbq('track', 'EventName', {
  content_ids: ['123', '456'],     // Array of product IDs (strings)
  content_name: 'Product Name',    // Optional
  content_type: 'product',         // 'product' or 'product_group'
  contents: [                      // Array of product objects
    {id: '123', quantity: 2},
    {id: '456', quantity: 1}
  ],
  value: 29.99,                    // Number without currency symbol
  currency: 'USD',                 // 3-letter ISO code
  num_items: 3                     // Total quantity
});

Standard Event Implementation

Add to Ecwid's Custom JavaScript Code section (Settings → General → Tracking & Analytics).

1. ViewContent (Product Views)

Fire when customer views a product detail page:

Ecwid.OnAPILoaded.add(function() {

  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'PRODUCT') {

      Ecwid.getProduct(page.productId, function(product) {

        fbq('track', 'ViewContent', {
          content_ids: [product.id.toString()],
          content_name: product.name,
          content_category: getCategoryName(product.categoryIds),
          content_type: 'product',
          value: product.defaultDisplayedPrice,
          currency: product.currency || 'USD'
        });
      });
    }
  });

  // Helper function
  function getCategoryName(categoryIds) {
    if (!categoryIds || categoryIds.length === 0) return '';
    return 'Category ' + categoryIds[0];
  }

});

Fire when customer uses search:

Ecwid.OnAPILoaded.add(function() {

  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'SEARCH' && page.keywords) {

      fbq('track', 'Search', {
        search_string: page.keywords
      });
    }
  });

});

3. AddToCart

Fire when item is added to cart:

Ecwid.OnAPILoaded.add(function() {

  var previousCart = null;

  Ecwid.OnCartChanged.add(function(cart) {

    // Initialize previous cart
    if (previousCart === null) {
      previousCart = JSON.parse(JSON.stringify(cart));
      return;
    }

    // Detect new items added
    if (cart.items.length > previousCart.items.length) {

      // Find the newly added item
      var newItem = cart.items.find(function(cartItem) {
        return !previousCart.items.some(function(prevItem) {
          return prevItem.id === cartItem.id;
        });
      });

      if (newItem) {
        fbq('track', 'AddToCart', {
          content_ids: [newItem.product.id.toString()],
          content_name: newItem.product.name,
          content_type: 'product',
          contents: [{
            id: newItem.product.id.toString(),
            quantity: newItem.quantity,
            item_price: newItem.price
          }],
          value: newItem.price * newItem.quantity,
          currency: cart.currency || 'USD'
        });
      }
    }

    // Detect quantity increases
    if (cart.items.length === previousCart.items.length) {
      cart.items.forEach(function(cartItem) {
        var prevItem = previousCart.items.find(function(prev) {
          return prev.id === cartItem.id;
        });

        if (prevItem && cartItem.quantity > prevItem.quantity) {
          var qtyAdded = cartItem.quantity - prevItem.quantity;

          fbq('track', 'AddToCart', {
            content_ids: [cartItem.product.id.toString()],
            content_name: cartItem.product.name,
            content_type: 'product',
            contents: [{
              id: cartItem.product.id.toString(),
              quantity: qtyAdded,
              item_price: cartItem.price
            }],
            value: cartItem.price * qtyAdded,
            currency: cart.currency || 'USD'
          });
        }
      });
    }

    // Update reference
    previousCart = JSON.parse(JSON.stringify(cart));
  });

});

4. InitiateCheckout

Fire when checkout process starts:

Ecwid.OnAPILoaded.add(function() {

  var checkoutStarted = false;

  Ecwid.OnPageLoad.add(function(page) {

    // Checkout starts at address page
    if (page.type === 'CHECKOUT_ADDRESS' && !checkoutStarted) {
      checkoutStarted = true;

      Ecwid.Cart.get(function(cart) {

        fbq('track', 'InitiateCheckout', {
          content_ids: cart.items.map(function(item) {
            return item.product.id.toString();
          }),
          contents: cart.items.map(function(item) {
            return {
              id: item.product.id.toString(),
              quantity: item.quantity,
              item_price: item.price
            };
          }),
          content_type: 'product',
          value: cart.total,
          currency: cart.currency || 'USD',
          num_items: cart.items.reduce(function(sum, item) {
            return sum + item.quantity;
          }, 0)
        });
      });
    }

    // Reset flag when leaving checkout
    if (page.type !== 'CHECKOUT_ADDRESS' &&
        page.type !== 'CHECKOUT_SHIPPING' &&
        page.type !== 'CHECKOUT_PAYMENT') {
      checkoutStarted = false;
    }
  });

});

5. AddPaymentInfo

Fire when customer enters payment step:

Ecwid.OnAPILoaded.add(function() {

  var paymentInfoAdded = false;

  Ecwid.OnPageLoad.add(function(page) {

    if (page.type === 'CHECKOUT_PAYMENT' && !paymentInfoAdded) {
      paymentInfoAdded = true;

      Ecwid.Cart.get(function(cart) {

        fbq('track', 'AddPaymentInfo', {
          content_ids: cart.items.map(function(item) {
            return item.product.id.toString();
          }),
          contents: cart.items.map(function(item) {
            return {
              id: item.product.id.toString(),
              quantity: item.quantity,
              item_price: item.price
            };
          }),
          content_type: 'product',
          value: cart.total,
          currency: cart.currency || 'USD'
        });
      });
    }

    // Reset when leaving payment page
    if (page.type !== 'CHECKOUT_PAYMENT') {
      paymentInfoAdded = false;
    }
  });

});

6. Purchase

Fire when order is successfully completed:

Ecwid.OnAPILoaded.add(function() {

  var purchaseTracked = false;

  Ecwid.OnOrderPlaced.add(function(order) {

    // Prevent duplicate tracking
    if (purchaseTracked) return;
    purchaseTracked = true;

    fbq('track', 'Purchase', {
      content_ids: order.items.map(function(item) {
        return item.product.id.toString();
      }),
      contents: order.items.map(function(item) {
        return {
          id: item.product.id.toString(),
          quantity: item.quantity,
          item_price: item.price
        };
      }),
      content_type: 'product',
      value: order.total,
      currency: order.currency || 'USD',
      num_items: order.items.reduce(function(sum, item) {
        return sum + item.quantity;
      }, 0)
    }, {
      eventID: 'order-' + order.vendorOrderNumber // For deduplication with CAPI
    });

    // Reset after delay
    setTimeout(function() {
      purchaseTracked = false;
    }, 5000);
  });

});

Custom Events

Track custom interactions specific to your store.

CompleteRegistration (Account Creation)

Track when customers create accounts:

Ecwid.OnAPILoaded.add(function() {

  var registrationTracked = false;

  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'ACCOUNT_SETTINGS') {

      Ecwid.getCustomerInfo(function(customer) {
        if (customer && customer.id && !registrationTracked) {
          registrationTracked = true;

          fbq('track', 'CompleteRegistration', {
            content_name: 'Customer Account',
            status: 'completed'
          });
        }
      });
    }
  });

});

AddToWishlist (Custom Wishlist)

If you implement a custom wishlist feature:

function addToWishlist(productId, productName, productPrice) {
  fbq('track', 'AddToWishlist', {
    content_ids: [productId.toString()],
    content_name: productName,
    content_type: 'product',
    value: productPrice,
    currency: 'USD'
  });
}

// Call when customer clicks wishlist button
document.querySelector('.wishlist-btn').addEventListener('click', function() {
  var productId = this.dataset.productId;
  var productName = this.dataset.productName;
  var productPrice = parseFloat(this.dataset.productPrice);

  addToWishlist(productId, productName, productPrice);
});

Subscribe (Newsletter Signup)

Track newsletter subscriptions:

// On host page newsletter form
document.getElementById('newsletter-form').addEventListener('submit', function(e) {
  e.preventDefault();

  fbq('track', 'Subscribe', {
    content_name: 'Newsletter',
    value: 0,
    currency: 'USD',
    predicted_ltv: 50.00 // Estimated customer lifetime value
  });

  // Submit form
  this.submit();
});

Contact (Contact Form)

Track contact form submissions:

document.getElementById('contact-form').addEventListener('submit', function(e) {
  fbq('track', 'Contact', {
    content_name: 'Contact Form',
    content_category: 'Customer Support'
  });
});

Custom Event: Product Variant Selection

Track when customers select product options:

Ecwid.OnAPILoaded.add(function() {

  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'PRODUCT') {

      // Track variant selection on add to cart
      Ecwid.OnCartChanged.add(function(cart) {
        var lastItem = cart.items[cart.items.length - 1];

        if (lastItem && lastItem.selectedOptions) {
          fbq('trackCustom', 'VariantSelected', {
            product_id: lastItem.product.id.toString(),
            product_name: lastItem.product.name,
            variant: lastItem.selectedOptions.map(function(opt) {
              return opt.name + ': ' + opt.value;
            }).join(', ')
          });
        }
      });
    }
  });

});

Custom Event: Coupon Usage

Track when customers apply discount coupons:

Ecwid.OnAPILoaded.add(function() {

  var previousCoupon = null;

  Ecwid.OnCartChanged.add(function(cart) {

    if (cart.couponDiscount && cart.couponDiscount > 0) {
      if (cart.couponName !== previousCoupon) {

        fbq('trackCustom', 'CouponApplied', {
          coupon_code: cart.couponName,
          discount_amount: cart.couponDiscount,
          currency: cart.currency || 'USD'
        });

        previousCoupon = cart.couponName;
      }
    } else {
      previousCoupon = null;
    }
  });

});

Advanced Tracking Patterns

Dynamic Product Ads (DPA)

Optimize for Dynamic Product Ads:

Ecwid.OnAPILoaded.add(function() {

  // ViewContent with detailed product data
  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'PRODUCT') {
      Ecwid.getProduct(page.productId, function(product) {

        fbq('track', 'ViewContent', {
          content_ids: [product.id.toString()],
          content_name: product.name,
          content_category: getCategoryPath(product.categoryIds),
          content_type: 'product',
          value: product.defaultDisplayedPrice,
          currency: product.currency || 'USD',
          // Additional DPA parameters
          availability: product.inStock ? 'in stock' : 'out of stock',
          condition: 'new',
          brand: product.brand || '',
          price: product.defaultDisplayedPrice,
          sale_price: product.compareToPrice > product.defaultDisplayedPrice ?
            product.defaultDisplayedPrice : undefined
        });
      });
    }
  });

  function getCategoryPath(categoryIds) {
    if (!categoryIds || categoryIds.length === 0) return '';
    // Fetch full category path if needed
    return 'Category ' + categoryIds[0];
  }

});

ViewCategory Event (Custom)

Track category page views for audience building:

Ecwid.OnAPILoaded.add(function() {

  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'CATEGORY') {

      fbq('trackCustom', 'ViewCategory', {
        category_id: page.categoryId.toString(),
        category_name: 'Category ' + page.categoryId // Or fetch actual name
      });
    }
  });

});

Engagement Tracking

Track engagement metrics:

Ecwid.OnAPILoaded.add(function() {

  var engagementStartTime = Date.now();

  // Track time spent on product page
  Ecwid.OnPageLoad.add(function(page) {
    if (page.type === 'PRODUCT') {
      engagementStartTime = Date.now();
    } else {
      var timeSpent = (Date.now() - engagementStartTime) / 1000;

      // Track if spent more than 10 seconds
      if (timeSpent > 10) {
        fbq('trackCustom', 'ProductEngagement', {
          time_spent: Math.round(timeSpent),
          engaged: timeSpent > 30
        });
      }
    }
  });

});

Event Deduplication

Prevent duplicate events when using both browser pixel and Conversions API:

Browser Pixel with Event ID

Ecwid.OnAPILoaded.add(function() {

  Ecwid.OnOrderPlaced.add(function(order) {

    var eventID = 'order-' + order.vendorOrderNumber;

    fbq('track', 'Purchase', {
      // ... event parameters
    }, {
      eventID: eventID  // Unique event identifier
    });
  });

});

Server-Side Conversions API

Use same eventID in your server-side request:

// In your webhook handler
{
  event_name: 'Purchase',
  event_id: 'order-' + order.vendorOrderNumber,  // Same ID
  event_time: Math.floor(Date.now() / 1000),
  // ... rest of data
}

Meta will deduplicate events with matching event_id within 48 hours.

Advanced Matching

Send hashed customer data for better attribution:

Ecwid.OnAPILoaded.add(function() {

  Ecwid.getCustomerInfo(function(customer) {
    if (customer && customer.email) {

      // Re-initialize pixel with advanced matching
      fbq('init', '1234567890123456', {
        em: customer.email.toLowerCase().trim(),
        fn: customer.firstName ? customer.firstName.toLowerCase().trim() : undefined,
        ln: customer.lastName ? customer.lastName.toLowerCase().trim() : undefined,
        ph: customer.phone ? customer.phone.replace(/[^0-9]/g, '') : undefined,
        external_id: customer.id.toString()
      });

      // Re-track PageView with customer data
      fbq('track', 'PageView');
    }
  });

});

Note: Meta automatically hashes this data. Ensure privacy policy compliance.

Implement GDPR/CCPA compliant tracking:

Delayed Loading

Only load pixel after consent:

var pixelLoaded = false;

function loadMetaPixel() {
  if (pixelLoaded) return;
  pixelLoaded = true;

  // Load base pixel code
  !function(f,b,e,v,n,t,s){...}(window, document,'script',...);

  fbq('init', '1234567890123456');
  fbq('track', 'PageView');

  // Initialize Ecwid tracking
  initializeEcwidTracking();
}

// Call when user accepts cookies
document.getElementById('accept-cookies').addEventListener('click', function() {
  loadMetaPixel();
});

function initializeEcwidTracking() {
  Ecwid.OnAPILoaded.add(function() {
    // All your Ecwid event tracking here
  });
}

Limited Data Use

For California residents (CCPA):

fbq('dataProcessingOptions', ['LDU'], 1, 1000); // 1 = California, 1000 = state code
function revokeConsent() {
  fbq('consent', 'revoke');
}

Debugging Events

Enable Test Mode

Use test event code for development:

fbq('init', '1234567890123456', {}, {
  agent: 'test_agent',  // Mark as test traffic
  autoConfig: true
});

Console Logging

Log all events to console:

var originalFbq = window.fbq;
window.fbq = function() {
  console.log('Meta Pixel Event:', arguments);
  return originalFbq.apply(this, arguments);
};

Check Event Queue

// View all queued events
console.log(window._fbq.queue);

Testing Checklist

  • Pixel loads - Meta Pixel Helper shows green icon
  • PageView - Fires on all pages
  • ViewContent - Fires on product pages with product data
  • Search - Fires when search used
  • AddToCart - Fires when item added, correct value
  • InitiateCheckout - Fires once at checkout start
  • AddPaymentInfo - Fires on payment page
  • Purchase - Fires on order completion with correct total
  • Event deduplication - No duplicate events
  • Parameters correct - All required params present
  • Currency correct - Matches store currency
  • Content IDs - Are strings in array format
  • Custom events - Fire as expected

Common Issues

Events Fire Multiple Times

Cause: Event listeners attached multiple times or page reloads.

Fix: Use flags to prevent duplicates:

var eventFired = false;

Ecwid.OnOrderPlaced.add(function(order) {
  if (eventFired) return;
  eventFired = true;

  fbq('track', 'Purchase', {...});

  setTimeout(function() {
    eventFired = false;
  }, 5000);
});

Missing content_ids

Cause: IDs not converted to strings or not in array.

Fix: Always format correctly:

// Wrong
content_ids: product.id,

// Correct
content_ids: [product.id.toString()],

Value includes currency symbol

Cause: Passing formatted price string instead of number.

Fix:

// Wrong
value: '$29.99',

// Correct
value: 29.99,

Ecwid API not available

Cause: Code runs before Ecwid loads.

Fix: Always wrap in Ecwid.OnAPILoaded.add():

Ecwid.OnAPILoaded.add(function() {
  // All tracking code here
});

Meta Pixel Helper Error Messages

"Invalid or Missing Parameters"

Fix: Ensure all required parameters are present and formatted correctly.

"Duplicate Pixel Code"

Fix: Remove duplicate pixel implementations (check built-in integration, custom code, GTM).

"No Pixel Found"

Fix: Verify pixel code is in Custom JavaScript Code section and Pixel ID is correct.

Next Steps

For general Meta Pixel concepts, see Meta Pixel Guide.