Ecwid provides multiple ways to track user interactions beyond basic pageviews. This guide covers standard ecommerce events, custom events, and advanced tracking using the Ecwid JavaScript API.
Ecwid's Native Event Tracking
When using Ecwid's built-in GA4 integration or proper custom implementation, these events are tracked automatically.
Automatically Tracked Events
| Event | When It Fires | Data Included |
|---|---|---|
view_item |
Customer views product detail | Product ID, name, price, category |
view_item_list |
Customer views category/search | Multiple products with positions |
add_to_cart |
Item added to cart | Product data, quantity, price |
remove_from_cart |
Item removed from cart | Product data, quantity |
view_cart |
Customer opens cart | Cart contents, total value |
begin_checkout |
Checkout process starts | Full cart data |
add_shipping_info |
Shipping method selected | Shipping cost, method |
add_payment_info |
Payment method selected | Payment method type |
purchase |
Order completed | Transaction ID, revenue, items, tax, shipping |
Event Data Structure
All events follow GA4's recommended ecommerce event structure:
gtag('event', 'event_name', {
currency: 'USD',
value: 29.99,
items: [{
item_id: '123',
item_name: 'Product Name',
item_category: 'Category',
price: 29.99,
quantity: 1
}]
});
Using Ecwid JavaScript API for Custom Tracking
The Ecwid JavaScript API provides hooks to track virtually any interaction. This is the most powerful method for custom event tracking.
API Initialization
Always wait for Ecwid to load before using the API:
<script>
// Wait for Ecwid API to load
Ecwid.OnAPILoaded.add(function() {
console.log('Ecwid API ready');
// Your tracking code here
});
</script>
Add this to Settings → General → Tracking & Analytics → Custom JavaScript Code.
Standard Ecommerce Events
1. Product View (view_item)
Fires when customer views a product detail page.
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
// Check if product page
if (page.type === 'PRODUCT') {
// Fetch full product details
Ecwid.getProduct(page.productId, function(product) {
// Get selected variant (if applicable)
var selectedOptions = product.options || [];
var selectedPrice = product.defaultDisplayedPrice;
gtag('event', 'view_item', {
currency: product.currency || 'USD',
value: selectedPrice,
items: [{
item_id: product.id.toString(),
item_name: product.name,
item_brand: product.brand || '',
item_category: getCategoryName(product.categoryIds[0]),
item_variant: getVariantName(selectedOptions),
price: selectedPrice,
quantity: 1
}]
});
});
}
});
// Helper function to get category name
function getCategoryName(categoryId) {
if (!categoryId) return '';
// Optionally fetch category details
return 'Category ' + categoryId;
}
// Helper function to format variant
function getVariantName(options) {
if (!options || options.length === 0) return '';
return options.map(opt => opt.value).join(' / ');
}
});
2. Category View (view_item_list)
Fires when customer views a category or search results.
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'CATEGORY' || page.type === 'SEARCH') {
var listName = page.type === 'CATEGORY' ?
'Category: ' + page.categoryId :
'Search: ' + page.keywords;
// Get products in view
Ecwid.getProducts({
categoryId: page.categoryId,
keyword: page.keywords,
limit: 50
}, function(products) {
var items = products.items.map(function(product, index) {
return {
item_id: product.id.toString(),
item_name: product.name,
item_list_name: listName,
item_list_id: page.categoryId ? page.categoryId.toString() : 'search',
index: index,
price: product.defaultDisplayedPrice,
quantity: 1
};
});
gtag('event', 'view_item_list', {
item_list_name: listName,
item_list_id: page.categoryId ? page.categoryId.toString() : 'search',
items: items
});
});
}
});
});
3. Add to Cart (add_to_cart)
Fires when customer adds item to cart.
Ecwid.OnAPILoaded.add(function() {
var previousCart = null;
Ecwid.OnCartChanged.add(function(cart) {
// Detect newly added items
if (previousCart && cart.items.length > previousCart.items.length) {
// Find the new item (last in array)
var newItem = cart.items[cart.items.length - 1];
gtag('event', 'add_to_cart', {
currency: cart.currency || 'USD',
value: newItem.price * newItem.quantity,
items: [{
item_id: newItem.product.id.toString(),
item_name: newItem.product.name,
price: newItem.price,
quantity: newItem.quantity
}]
});
}
// Update previous cart reference
previousCart = JSON.parse(JSON.stringify(cart));
});
});
4. Remove from Cart (remove_from_cart)
Fires when customer removes item from cart.
Ecwid.OnAPILoaded.add(function() {
var previousCart = null;
Ecwid.OnCartChanged.add(function(cart) {
// Detect removed items
if (previousCart && cart.items.length < previousCart.items.length) {
// Find removed item by comparing arrays
var removedItem = previousCart.items.find(function(prevItem) {
return !cart.items.some(function(currItem) {
return currItem.id === prevItem.id;
});
});
if (removedItem) {
gtag('event', 'remove_from_cart', {
currency: cart.currency || 'USD',
value: removedItem.price * removedItem.quantity,
items: [{
item_id: removedItem.product.id.toString(),
item_name: removedItem.product.name,
price: removedItem.price,
quantity: removedItem.quantity
}]
});
}
}
previousCart = JSON.parse(JSON.stringify(cart));
});
});
5. Begin Checkout (begin_checkout)
Fires when customer starts checkout process.
Ecwid.OnAPILoaded.add(function() {
var checkoutStarted = false;
Ecwid.OnPageLoad.add(function(page) {
// Checkout starts at address entry step
if (page.type === 'CHECKOUT_ADDRESS' && !checkoutStarted) {
checkoutStarted = true;
Ecwid.Cart.get(function(cart) {
gtag('event', 'begin_checkout', {
currency: cart.currency || 'USD',
value: cart.total,
items: cart.items.map(function(item) {
return {
item_id: item.product.id.toString(),
item_name: item.product.name,
price: item.price,
quantity: item.quantity
};
})
});
});
}
// Reset flag when leaving checkout
if (page.type !== 'CHECKOUT_ADDRESS' && page.type !== 'CHECKOUT_SHIPPING' && page.type !== 'CHECKOUT_PAYMENT') {
checkoutStarted = false;
}
});
});
6. Add Shipping Info (add_shipping_info)
Fires when customer selects shipping method.
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'CHECKOUT_PAYMENT') {
// Customer moved to payment, shipping selected
Ecwid.Cart.get(function(cart) {
var shippingOption = cart.shippingOption || {};
gtag('event', 'add_shipping_info', {
currency: cart.currency || 'USD',
value: cart.total,
shipping_tier: shippingOption.shippingMethodName || 'Unknown',
items: cart.items.map(function(item) {
return {
item_id: item.product.id.toString(),
item_name: item.product.name,
price: item.price,
quantity: item.quantity
};
})
});
});
}
});
});
7. Add Payment Info (add_payment_info)
Fires when customer selects payment method.
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'CHECKOUT_PAYMENT') {
// Payment page loaded
// Note: Ecwid API doesn't expose selected payment method
// Track that payment step was reached
Ecwid.Cart.get(function(cart) {
gtag('event', 'add_payment_info', {
currency: cart.currency || 'USD',
value: cart.total,
payment_type: 'Unknown', // Ecwid doesn't provide this
items: cart.items.map(function(item) {
return {
item_id: item.product.id.toString(),
item_name: item.product.name,
price: item.price,
quantity: item.quantity
};
})
});
});
}
});
});
8. Purchase (purchase)
Fires when order is completed successfully.
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnOrderPlaced.add(function(order) {
gtag('event', 'purchase', {
transaction_id: order.vendorOrderNumber,
value: order.total,
tax: order.tax || 0,
shipping: order.shippingOption ? order.shippingOption.shippingRate : 0,
currency: order.currency || 'USD',
coupon: order.couponDiscount > 0 ? order.couponName : '',
items: order.items.map(function(item) {
return {
item_id: item.product.id.toString(),
item_name: item.product.name,
price: item.price,
quantity: item.quantity,
discount: item.discount || 0
};
})
});
});
});
Custom Event Tracking
Track custom interactions specific to your store.
Newsletter Signup
// Assuming newsletter form on host page
document.getElementById('newsletter-form').addEventListener('submit', function(e) {
gtag('event', 'newsletter_signup', {
method: 'Footer Form'
});
});
Search (Site Search)
Track when customers use Ecwid's search:
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'SEARCH' && page.keywords) {
gtag('event', 'search', {
search_term: page.keywords
});
}
});
});
Filter Usage
Track when customers use category filters:
Ecwid.OnAPILoaded.add(function() {
// Listen to filter changes
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'CATEGORY') {
// Track category view with filters
gtag('event', 'filter_applied', {
filter_type: 'category',
category_id: page.categoryId
});
}
});
});
Product Wishlist (if implemented)
// Custom wishlist implementation
function addToWishlist(productId, productName) {
gtag('event', 'add_to_wishlist', {
currency: 'USD',
value: 0, // Or product price if available
items: [{
item_id: productId.toString(),
item_name: productName
}]
});
}
Social Share
Track when customers share products:
// Social share buttons
document.querySelectorAll('.social-share').forEach(function(btn) {
btn.addEventListener('click', function() {
var network = this.dataset.network; // facebook, twitter, etc.
var productId = this.dataset.productId;
gtag('event', 'share', {
method: network,
content_type: 'product',
content_id: productId
});
});
});
Advanced Tracking Patterns
User Authentication
Track when customers log in or create accounts:
Ecwid.OnAPILoaded.add(function() {
// Track login
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'ACCOUNT_SETTINGS') {
// Customer logged in and viewing account
Ecwid.getCustomerInfo(function(customer) {
if (customer && customer.id) {
gtag('event', 'login', {
method: 'Ecwid Account'
});
// Set user ID for cross-session tracking
gtag('config', 'G-XXXXXXXXXX', {
'user_id': customer.id.toString()
});
}
});
}
});
});
Promotion Clicks
Track when customers click promotional banners:
// For custom promo banners on host page
document.querySelectorAll('.promo-banner').forEach(function(banner) {
banner.addEventListener('click', function() {
gtag('event', 'select_promotion', {
promotion_id: this.dataset.promoId,
promotion_name: this.dataset.promoName,
creative_name: this.dataset.creativeName,
creative_slot: this.dataset.slot
});
});
});
Product Variant Selection
Track when customers select product options:
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
if (page.type === 'PRODUCT') {
// Note: Ecwid doesn't provide direct variant change event
// Alternative: Track after option selection leads to add to cart
Ecwid.OnCartChanged.add(function(cart) {
var lastItem = cart.items[cart.items.length - 1];
if (lastItem && lastItem.selectedOptions) {
gtag('event', 'variant_selected', {
item_id: lastItem.product.id.toString(),
item_name: lastItem.product.name,
variant: lastItem.selectedOptions.map(opt => opt.value).join(' / ')
});
}
});
}
});
});
Enhanced Ecommerce with User Properties
Set custom user properties for better segmentation:
Ecwid.OnAPILoaded.add(function() {
Ecwid.getCustomerInfo(function(customer) {
if (customer && customer.id) {
// Set user properties
gtag('set', 'user_properties', {
customer_id: customer.id.toString(),
customer_type: customer.customerGroupId ? 'wholesale' : 'retail',
lifetime_orders: customer.orderCount || 0,
lifetime_value: customer.totalSpent || 0
});
}
});
});
Consent Management
Implement GDPR/CCPA compliant tracking:
Default Consent State
// Set default consent before GA4 loads
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'wait_for_update': 500
});
// Initialize GA4
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
Update Consent on User Action
// When user accepts cookies
function acceptCookies() {
gtag('consent', 'update', {
'analytics_storage': 'granted',
'ad_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted'
});
}
// When user rejects
function rejectCookies() {
gtag('consent', 'update', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied'
});
}
Debugging Events
Enable Debug Mode
gtag('config', 'G-XXXXXXXXXX', {
'debug_mode': true
});
Console Logging
Add logging to track what fires:
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnPageLoad.add(function(page) {
console.log('Ecwid Page Loaded:', page.type);
});
Ecwid.OnCartChanged.add(function(cart) {
console.log('Cart Changed:', cart);
});
Ecwid.OnOrderPlaced.add(function(order) {
console.log('Order Placed:', order);
});
});
Check Data Layer
// View all data layer events
console.table(window.dataLayer);
// Filter specific events
console.log(
window.dataLayer.filter(item => item.event === 'purchase')
);
Testing Checklist
- Product view -
view_itemfires with correct product data - Category view -
view_item_listincludes multiple products - Add to cart -
add_to_cartfires with quantity - Remove from cart -
remove_from_cartdetects removals - Begin checkout -
begin_checkoutfires on first checkout step - Purchase -
purchasefires with transaction ID and revenue - Custom events - All custom events fire as expected
- User properties - Set correctly for logged-in users
- No duplicates - Events don't fire multiple times
- Consent respected - Tracking honors consent choices
Common Issues
Events Fire Multiple Times
Cause: Event listeners attached multiple times.
Fix: Use flags to prevent duplicate tracking:
var eventFired = false;
Ecwid.OnOrderPlaced.add(function(order) {
if (eventFired) return;
eventFired = true;
// Track purchase
gtag('event', 'purchase', {...});
});
Ecwid API Not Available
Cause: Code runs before Ecwid loads.
Fix: Always wrap in Ecwid.OnAPILoaded.add():
// Wrong
Ecwid.OnCartChanged.add(function(cart) {
// Won't work if Ecwid not loaded yet
});
// Correct
Ecwid.OnAPILoaded.add(function() {
Ecwid.OnCartChanged.add(function(cart) {
// Guaranteed to work
});
});
Missing Product Data
Cause: API not returning full product details.
Fix: Use Ecwid.getProduct() to fetch complete data:
// Instead of relying on page data
Ecwid.getProduct(productId, function(product) {
// Full product details available here
});
Next Steps
- GA4 Ecommerce Tracking - Advanced product and revenue tracking
- GTM Data Layer - Use GTM for easier event management
- Events Not Firing - Troubleshoot tracking issues
For general GA4 event concepts, see GA4 Event Tracking Guide.