
Storefront events on Zid: track views, carts and purchases from your app scripts
Which storefront events Zid exposes, what each payload contains, how to add tracking scripts through Custom Snippets, and the zidTracking helpers for theme developers.
What the event layer is for
App Scripts let your app insert JavaScript into merchant storefronts without the merchant editing any code. Zid lists uses such as conversion tracking, analytics, personalization and customizing storefront interactions. The docs describe the storefront events as officially exposed for client-side tracking and integration, whether your app is embedded in the merchant dashboard or external.
There are two kinds of script:
- Global scripts load on every page.
- Event-driven scripts run in response to a shopper's action, such as viewing a product, adding it to the cart or completing a purchase.
order.create, which Zid sends to your server. A good split is to rely on webhooks for authoritative order data and on storefront events for what happens in the browser.Global objects: who is the shopper?
Three objects are available in the page's window scope:
window.customer: the logged-in customer, withid,name,firstname,lastname,mobileandemail. It's empty when nobody is logged in.window.customerAuthState: available immediately on page load, withisAuthenticatedandisGuest.window.customerAsync: a Promise that resolves with the customer data once it's fetched, useful whenwindow.customerisn't ready yet.
(async function () {
var auth = window.customerAuthState || {};
if (!auth.isAuthenticated) return; // guest or logged out
var customer = (window.customer && window.customer.id)
? window.customer
: await window.customerAsync;
// use customer.id to map the shopper to your own records
})();The seven supported events
- Purchase: after a successful transaction.
- Product View: when a shopper views a product (
productViewd). - Add to Cart: when a product is added to the cart (
productCart). - Remove from Cart: when a product is removed from the cart (
productCart). - Start Checkout: when the shopper starts checkout.
- View Item List (new): when a list of products is viewed, such as a category page or search results.
- Select Item (new): when a shopper clicks a product in a list.
The unusual spellings productViewd and productCart are intentional. They match Zid's codebase, so use them exactly as written.
Product View, Add to Cart and Remove from Cart carry a single product object with id, name, sku, category, price and position (display order), and the two cart events add quantity. Select Item carries product (same structure as productViewd) and listName. View Item List carries listName and a products array with item_id, item_name, item_sku, currency, price, quantity and item_category.
Purchase and checkout payloads, current and legacy
The Purchase event carries order (the full order object), transaction_id (the order ID), value, currency and an items array. This example is built from the documented fields:
{
"transaction_id": "order-123",
"value": 199.98,
"currency": "SAR",
"items": [
{
"item_id": "product-1",
"item_name": "Product Name",
"item_sku": "SKU-123",
"price": 99.99,
"quantity": 2,
"item_category": "Category Name"
}
],
"order": { }
}Start Checkout now receives the full cart object: id, session_id, products (with product_id, name, sku, price and quantity), products_count, products_subtotal, totals, currency (the code is in cart_currency.code) and coupon.
Both events also have a documented legacy shape. Legacy Purchase sends a flat transactionItems array with the order number in id. Legacy Start Checkout sends flat fields such as cart_id, cart_total, currency and items, whose entries have item_id, item_name, item_price and item_quantity. If your script may meet both, normalize first:
function normalizePurchase(evt) {
if (evt.items) {
return { orderId: evt.transaction_id, value: evt.value,
currency: evt.currency, items: evt.items };
}
var legacy = evt.transactionItems || [];
return {
orderId: evt.id,
value: legacy.reduce(function (s, i) { return s + Number(i.total || 0); }, 0),
currency: legacy.length ? legacy[0].currency : undefined,
items: legacy.map(function (i) {
return { item_id: i.id, item_name: i.name, item_sku: i.sku,
price: i.price, quantity: i.quantity, item_category: i.category };
})
};
}Delivering your script with Custom Snippets
- Open your app in the Partner Dashboard and go to General Settings.
- Click Add Snippet and enter your JavaScript or CSS.
- Choose the snippet's placement (such as header or footer) and configure any required parameters.
- Submit it for review and approval. You can modify or remove it at any time.
For mobile and hybrid setups, the documented Scripts manifest (GET /api/v1/scripts) shows how snippets are grouped: external_scripts holds approved remote script URLs, and app_scripts_bundle holds inline snippets under reserved keys: head, global_head_script, purchase_event, product_details_event, add_to_cart_event, remove_from_cart_event and start_checkout_event, plus params for identifiers such as pixel IDs.
Your script may run on a Vitrin theme or a legacy theme. Check window.vitrin, which is true only on Vitrin stores. If your remote script already uses query params, it receives vitrin=true on Vitrin stores, so you can serve a newer version without checking inside the script:
// Inside your script
var hasVitrin = window.vitrin == true;
// How Zid calls a remote script URL:
// Vitrin: {script_url}?store={store_uuid}&vitrin=true
// Legacy: {script_url}?store={store_uuid}For theme developers: zidTracking
The JS Integration docs list two tracking events that theme developers call manually. Both are available on window.zidTracking:
zidTracking.sendGaSelectItemEvent({ product, listName, listId, index })when a shopper clicks a product in a list, such as a related-products slider. Onlyproductis required,listNamedefaults to"products", andindexis 0-based. It's sent asselect_itemto GA4 and GTM.zidTracking.sendGaCartDetailViewedEvent({ cart })when you show cart contents outside the cart page, such as a mini-cart or drawer. It's sent asview_cartto GA4 and GTM, and asViewCartto Facebook.
// Product card click in a list
zidTracking.sendGaSelectItemEvent({
product: product,
listName: 'Related Products',
listId: 'related_products_pdp',
index: 2
});
// Cart drawer opened (not on /cart)
const cart = await zid.cart.get();
window.zidTracking?.sendGaCartDetailViewedEvent({ cart });view_cart fires automatically on the /cart page. Don't call it there, or it will be counted twice.Key takeaways
- Zid exposes seven storefront events: purchase, product view, add to cart, remove from cart, start checkout, view item list and select item.
- Use
window.customerAuthStatefor instant login state, andwindow.customerAsyncwhenwindow.customerisn't ready. - Handle both the current and legacy payloads for purchase and start checkout.
- Ship your scripts through Custom Snippets in the Partner Dashboard; they're reviewed before going live.
- Theme developers call
sendGaSelectItemEventandsendGaCartDetailViewedEventmanually, and never callview_carton/cart.
Sources
Start building on Zid
Sign up in the partner portal, then build and test on a development store.


