Squarespace Commerce + GA4 Ecommerce Tracking
Squarespace Commerce provides basic transaction data, but implementing full GA4 eCommerce tracking requires custom code to capture the complete customer journey from product views to purchase.
Overview
GA4 eCommerce tracking captures:
- Product impressions - Products viewed on collection/shop pages
- Product detail views - Individual product page views
- Add to cart - Items added to cart
- Remove from cart - Items removed from cart
- Begin checkout - Checkout process started
- Purchase - Completed transactions
Prerequisites
Before implementing:
- Have GA4 installed on your Squarespace site (see GA4 Setup)
- Have a Squarespace Commerce plan (Business or Commerce)
- Know your store's currency code (USD, EUR, GBP, etc.)
Order Confirmation Tracking (Purchase Event)
The most critical eCommerce event is the purchase event, which fires on the order confirmation page.
Implementation
- Go to Settings > Advanced > Code Injection
- Scroll to ORDER CONFIRMATION PAGE section
- Add the following code:
<!-- GA4 Ecommerce Purchase Tracking -->
<script>
(function() {
// Get order data from Squarespace
var orderData = {orderInformation};
if (orderData && typeof gtag !== 'undefined') {
// Prepare items array
var items = orderData.lineItems.map(function(item, index) {
return {
'item_id': item.sku || item.productId,
'item_name': item.productName,
'item_variant': item.variantOptions ? item.variantOptions.join(', ') : undefined,
'price': item.unitPricePaid.value,
'quantity': item.quantity,
'index': index
};
});
// Send purchase event
gtag('event', 'purchase', {
'transaction_id': orderData.id,
'value': orderData.grandTotal.value,
'currency': orderData.grandTotal.currency,
'tax': orderData.salesTax ? orderData.salesTax.value : 0,
'shipping': orderData.shippingTotal.value,
'items': items
});
// Also send to GA4 as ecommerce event
gtag('event', 'purchase', {
'send_to': 'G-XXXXXXXXXX', // Replace with your Measurement ID
'transaction_id': orderData.id,
'affiliation': 'Squarespace Store',
'value': orderData.grandTotal.value,
'currency': orderData.grandTotal.currency,
'tax': orderData.salesTax ? orderData.salesTax.value : 0,
'shipping': orderData.shippingTotal.value,
'items': items
});
}
})();
</script>
Important: Replace G-XXXXXXXXXX with your actual GA4 Measurement ID.
Available Order Data
Squarespace provides the {orderInformation} variable with:
id- Order IDgrandTotal- Total order valuesubtotal- Subtotal before tax/shippingsalesTax- Tax amountshippingTotal- Shipping costlineItems- Array of purchased productscustomerEmail- Customer email (use carefully for privacy)
Product Detail Views
Track when users view individual product pages:
Implementation
Add to Footer Code Injection:
<script>
document.addEventListener('DOMContentLoaded', function() {
// Check if this is a product page
var productBlock = document.querySelector('.sqs-commerce-product-detail');
if (productBlock && typeof gtag !== 'undefined') {
// Extract product data
var productName = document.querySelector('.product-title') ?
document.querySelector('.product-title').textContent.trim() :
'Unknown Product';
var productPrice = document.querySelector('.product-price') ?
parseFloat(document.querySelector('.product-price').textContent.replace(/[^0-9.]/g, '')) :
0;
var productId = getProductIdFromUrl();
// Send view_item event
gtag('event', 'view_item', {
'currency': 'USD', // Update to your currency
'value': productPrice,
'items': [{
'item_id': productId,
'item_name': productName,
'price': productPrice
}]
});
}
function getProductIdFromUrl() {
// Extract product slug from URL
var pathParts = window.location.pathname.split('/');
var productSlug = pathParts[pathParts.length - 1] || pathParts[pathParts.length - 2];
return productSlug;
}
});
</script>
Enhanced Product Detail Tracking
For more detailed product data, including variants and categories:
<script>
document.addEventListener('DOMContentLoaded', function() {
var productBlock = document.querySelector('.sqs-commerce-product-detail');
if (productBlock && typeof gtag !== 'undefined') {
// Wait for Squarespace Commerce to load product data
if (window.Static && window.Static.SQUARESPACE_CONTEXT && window.Static.SQUARESPACE_CONTEXT.product) {
var product = window.Static.SQUARESPACE_CONTEXT.product;
gtag('event', 'view_item', {
'currency': 'USD',
'value': product.variants[0].priceMoney.value / 100, // Convert cents to dollars
'items': [{
'item_id': product.id,
'item_name': product.title,
'item_category': product.categories && product.categories[0] ? product.categories[0] : undefined,
'price': product.variants[0].priceMoney.value / 100,
'item_variant': product.variants[0].attributes ? JSON.stringify(product.variants[0].attributes) : undefined
}]
});
}
}
});
</script>
Add to Cart Event
Track when products are added to the cart:
<script>
(function() {
if (window.Y && window.Y.Squarespace && typeof gtag !== 'undefined') {
window.Y.use(function(Y) {
// Listen for cart add events
Y.on('cart:item:added', function(e) {
var item = e.item;
gtag('event', 'add_to_cart', {
'currency': 'USD',
'value': item.price / 100, // Squarespace uses cents
'items': [{
'item_id': item.sku || item.id,
'item_name': item.title,
'price': item.price / 100,
'quantity': item.quantity,
'item_variant': item.chosenVariant ? item.chosenVariant.attributes : undefined
}]
});
});
});
}
})();
</script>
Remove from Cart Event
Track cart removals:
<script>
(function() {
if (window.Y && window.Y.Squarespace && typeof gtag !== 'undefined') {
window.Y.use(function(Y) {
Y.on('cart:item:removed', function(e) {
var item = e.item;
gtag('event', 'remove_from_cart', {
'currency': 'USD',
'value': item.price / 100,
'items': [{
'item_id': item.sku || item.id,
'item_name': item.title,
'price': item.price / 100,
'quantity': item.quantity
}]
});
});
});
}
})();
</script>
Begin Checkout Event
Track when users start the checkout process:
<script>
document.addEventListener('DOMContentLoaded', function() {
// Detect checkout page
if (window.location.pathname.includes('/checkout') && typeof gtag !== 'undefined') {
// Get cart data from Squarespace
if (window.Y && window.Y.Squarespace) {
window.Y.use(function(Y) {
var cart = Y.Squarespace.Commerce.getCart();
if (cart && cart.entries && cart.entries.length > 0) {
var items = cart.entries.map(function(entry) {
return {
'item_id': entry.sku || entry.id,
'item_name': entry.title,
'price': entry.price / 100,
'quantity': entry.quantity
};
});
gtag('event', 'begin_checkout', {
'currency': 'USD',
'value': cart.subtotal / 100,
'items': items
});
}
});
}
}
});
</script>
Product List Views (Collections)
Track product impressions on shop/collection pages:
<script>
document.addEventListener('DOMContentLoaded', function() {
// Check if this is a shop/collection page
var productItems = document.querySelectorAll('.sqs-commerce-product-item');
if (productItems.length > 0 && typeof gtag !== 'undefined') {
var items = [];
productItems.forEach(function(item, index) {
var titleEl = item.querySelector('.product-title');
var priceEl = item.querySelector('.product-price');
var linkEl = item.querySelector('a[href*="/products/"]');
if (titleEl && priceEl) {
var productName = titleEl.textContent.trim();
var productPrice = parseFloat(priceEl.textContent.replace(/[^0-9.]/g, ''));
var productId = linkEl ? linkEl.getAttribute('href').split('/').pop() : 'unknown';
items.push({
'item_id': productId,
'item_name': productName,
'price': productPrice,
'index': index
});
}
});
if (items.length > 0) {
gtag('event', 'view_item_list', {
'item_list_id': 'product_collection',
'item_list_name': document.title,
'items': items
});
}
}
});
</script>
Product Clicks from Collections
Track when users click products from collection pages:
<script>
document.addEventListener('DOMContentLoaded', function() {
var productLinks = document.querySelectorAll('.sqs-commerce-product-item a[href*="/products/"]');
productLinks.forEach(function(link, index) {
link.addEventListener('click', function(e) {
var item = this.closest('.sqs-commerce-product-item');
var titleEl = item.querySelector('.product-title');
var priceEl = item.querySelector('.product-price');
if (titleEl && priceEl && typeof gtag !== 'undefined') {
var productName = titleEl.textContent.trim();
var productPrice = parseFloat(priceEl.textContent.replace(/[^0-9.]/g, ''));
var productId = this.getAttribute('href').split('/').pop();
gtag('event', 'select_item', {
'item_list_id': 'product_collection',
'item_list_name': document.title,
'items': [{
'item_id': productId,
'item_name': productName,
'price': productPrice,
'index': index
}]
});
}
});
});
});
</script>
Complete Implementation (All Events)
For a full implementation, combine all events in your Footer Code Injection:
<!-- GA4 Ecommerce Tracking - Complete Implementation -->
<script>
(function() {
var CURRENCY = 'USD'; // Update to your store's currency
// Add to Cart
if (window.Y && window.Y.Squarespace) {
window.Y.use(function(Y) {
Y.on('cart:item:added', function(e) {
if (typeof gtag !== 'undefined') {
gtag('event', 'add_to_cart', {
'currency': CURRENCY,
'value': e.item.price / 100,
'items': [{
'item_id': e.item.sku || e.item.id,
'item_name': e.item.title,
'price': e.item.price / 100,
'quantity': e.item.quantity
}]
});
}
});
Y.on('cart:item:removed', function(e) {
if (typeof gtag !== 'undefined') {
gtag('event', 'remove_from_cart', {
'currency': CURRENCY,
'value': e.item.price / 100,
'items': [{
'item_id': e.item.sku || e.item.id,
'item_name': e.item.title,
'price': e.item.price / 100,
'quantity': e.item.quantity
}]
});
}
});
});
}
// View Item (Product Detail)
document.addEventListener('DOMContentLoaded', function() {
var productBlock = document.querySelector('.sqs-commerce-product-detail');
if (productBlock && typeof gtag !== 'undefined') {
var productName = document.querySelector('.product-title') ?
document.querySelector('.product-title').textContent.trim() :
'Unknown Product';
var productPrice = document.querySelector('.product-price') ?
parseFloat(document.querySelector('.product-price').textContent.replace(/[^0-9.]/g, '')) :
0;
var productId = window.location.pathname.split('/').pop();
gtag('event', 'view_item', {
'currency': CURRENCY,
'value': productPrice,
'items': [{
'item_id': productId,
'item_name': productName,
'price': productPrice
}]
});
}
// Begin Checkout
if (window.location.pathname.includes('/checkout')) {
if (window.Y && window.Y.Squarespace) {
window.Y.use(function(Y) {
var cart = Y.Squarespace.Commerce.getCart();
if (cart && cart.entries && typeof gtag !== 'undefined') {
var items = cart.entries.map(function(entry) {
return {
'item_id': entry.sku || entry.id,
'item_name': entry.title,
'price': entry.price / 100,
'quantity': entry.quantity
};
});
gtag('event', 'begin_checkout', {
'currency': CURRENCY,
'value': cart.subtotal / 100,
'items': items
});
}
});
}
}
});
})();
</script>
Subscription Products
For Squarespace subscription products, add subscription-specific parameters:
gtag('event', 'add_to_cart', {
'currency': 'USD',
'value': item.price / 100,
'items': [{
'item_id': item.sku || item.id,
'item_name': item.title,
'price': item.price / 100,
'quantity': item.quantity,
'subscription': true,
'subscription_frequency': item.subscriptionPlan ? item.subscriptionPlan.frequency : undefined
}]
});
Digital Products
For digital product downloads:
// Track digital product download
gtag('event', 'file_download', {
'file_name': product.title,
'product_id': product.id,
'link_url': downloadUrl
});
Validating Ecommerce Tracking
1. GA4 DebugView
- Install Google Analytics Debugger extension
- Navigate to Configure > DebugView in GA4
- Go through the purchase funnel on your site
- Verify each event appears with correct parameters
2. Real-Time Reports
- Go to Reports > Realtime > Event count by Event name
- Trigger eCommerce events
- Confirm events appear in real-time
3. Ecommerce Purchases Report
After 24-48 hours:
- Navigate to Reports > Monetization > Ecommerce purchases
- Verify transaction data is appearing
- Check revenue, tax, and shipping values
Common Issues & Solutions
Issue: Purchase Event Not Firing
Cause: Code not added to Order Confirmation page section
Solution:
- Ensure code is in the ORDER CONFIRMATION PAGE section of Code Injection, NOT the site-wide footer
- Test by completing a real purchase (use a small value test product)
Issue: Wrong Currency or Prices
Cause: Squarespace stores prices in cents, not dollars
Solution:
- Always divide Squarespace price values by 100:
item.price / 100 - Update CURRENCY constant to match your store's currency
Issue: Missing Product IDs
Cause: Product doesn't have SKU defined
Solution:
- Use fallback to product ID:
item.sku || item.id - Ensure all products have SKUs in Squarespace admin
Issue: Duplicate Purchase Events
Cause: Customer refreshing order confirmation page
Solution: Add de-duplication check:
// Only fire purchase event once per order
var firedOrders = sessionStorage.getItem('ga4_orders') || '';
if (firedOrders.indexOf(orderData.id) === -1) {
// Send purchase event
gtag('event', 'purchase', { /* ... */ });
sessionStorage.setItem('ga4_orders', firedOrders + ',' + orderData.id);
}
Multi-Currency Stores
If your store operates in multiple currencies:
var CURRENCY_MAP = {
'US': 'USD',
'GB': 'GBP',
'EU': 'EUR'
};
var userCurrency = orderData.grandTotal.currency || 'USD';
gtag('event', 'purchase', {
'currency': userCurrency,
// ... rest of event
});
Best Practices
Always Include Required Parameters:
transaction_idfor purchase eventscurrencyfor all eCommerce eventsvaluefor monetary eventsitemsarray for all events
Use Consistent Item IDs:
- Preferably use SKUs
- Fall back to product IDs if SKUs unavailable
- Don't mix ID formats
Test in Squarespace Preview:
- Changes to Code Injection require saving and refreshing
- Test thoroughly before going live
- Complete full purchase flow in test mode
Monitor Revenue Data:
- Regularly compare GA4 revenue to Squarespace Commerce reports
- Investigate discrepancies immediately
- Account for refunds and cancellations
Next Steps
- Set up GTM for easier eCommerce tracking management
- Configure custom events for additional user interactions
- Troubleshoot tracking issues if events aren't working