Last active
October 7, 2025 08:19
-
-
Save borlaym/ed546dbe1dbe3e16fb073618ceec4e8a to your computer and use it in GitHub Desktop.
Updated Shopify Web Pixel code for Snowplow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[]; p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments) };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","//cdn.jsdelivr.net/npm/@snowplow/javascript-tracker@4/dist/sp.js","snowplow")); | |
| async function hashStringSHA256(inputString) { | |
| const encoder = new TextEncoder(); | |
| const data = encoder.encode(inputString); | |
| const hashBuffer = await crypto.subtle.digest('SHA-256', data); | |
| const hashArray = Array.from(new Uint8Array(hashBuffer)); | |
| const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); | |
| return hashHex; | |
| } | |
| async function createUserContext(checkout) { | |
| const userContext = { | |
| schema: "iglu:io.sspinc.partner/user/jsonschema/1-0-0", | |
| data: { | |
| userId: checkout.order.customer.id, | |
| }, | |
| }; | |
| if (checkout.email) { | |
| const emailHash = await hashStringSHA256(checkout.email); | |
| userContext.data.emailHash = emailHash; | |
| } | |
| return userContext; | |
| } | |
| var initCart = init.data.cart || {cost: { totalAmount: { amount: 0 }}}; | |
| snowplow('newTracker', 'sp', 'https://mini.sspinc.io', { | |
| appId: 'acme', | |
| credentials: 'same-origin', // important (NB: Network User ID will not function correctly) | |
| cookieDomain: 'secret-sauce-rabbit-v2.myshopify.com', // important: update with your production site domain; discoverRootDomain will not work in the sandbox | |
| anonymousTracking: false, // you may want to decide this based on init.customerPrivacy | |
| contexts: { | |
| webPage: true, // recommended, default | |
| session: true, // recommended | |
| browser: false, // limited support | |
| performanceTiming: false, // not supported | |
| gaCookies: false, // limited support | |
| geoLocation: false, // not supported | |
| clientHints: false, // limited support | |
| } | |
| }); | |
| snowplow('setCustomUrl', init.context.window.location.href); // otherwise this will point to the sandbox URL | |
| // - plugins like form and link tracking will not work automatically; you will need to wrap the Shopify events to explicit tracker calls | |
| // - page pings may not detect all activity as user interactions can not be measured | |
| // 'addPlugin' likely won't work as expected; load scripts manually and load them as inline plugins if required; or preferably bundle the plugins into your sp.js file: | |
| // https://docs.snowplow.io/docs/sources/trackers/javascript-trackers/web-tracker/plugins/creating-your-own-plugins/#inline-plugins | |
| // https://docs.snowplow.io/docs/sources/trackers/javascript-trackers/web-tracker/plugins/configuring-tracker-plugins/javascript/#custom-plugin-selections | |
| analytics.subscribe("page_viewed", (event) => { | |
| snowplow('setCustomUrl', event.context.window.location.href); | |
| snowplow('trackPageView'); | |
| }); | |
| analytics.subscribe("all_dom_events", (event) => { | |
| snowplow('setCustomUrl', event.context.window.location.href); | |
| snowplow('updatePageActivity'); // give a signal for page pings | |
| }); | |
| analytics.subscribe("snowplow_active", (event) => { | |
| snowplow('setCustomUrl', event.context.window.location.href); | |
| snowplow('updatePageActivity'); // give a signal for page pings | |
| }); | |
| analytics.subscribe("checkout_completed", function(event){ | |
| snowplow('setCustomUrl', event.context.window.location.href); | |
| var co = event.data.checkout; | |
| if (!co) return; | |
| var d = co.delivery && co.delivery.selectedDeliveryOptions && co.delivery.selectedDeliveryOptions[0]; | |
| var da = co.discountApplications && co.discountApplications[0]; | |
| var t = co.transactions && co.transactions[0]; | |
| window.innerWidth = init.context.window.innerWidth; | |
| window.innerHeight = init.context.window.innerHeight; | |
| createUserContext(co) | |
| .then(userContext => { | |
| const contexts = [ | |
| userContext, | |
| { | |
| schema: "iglu:io.sspinc.partner/page/jsonschema/1-0-0", | |
| data: { type: "ord" } | |
| }, | |
| { | |
| schema: "iglu:io.sspinc.partner/site/jsonschema/1-0-0", | |
| data: { | |
| currency: event.data.checkout.currencyCode, | |
| language: "en", | |
| market: "US" | |
| } | |
| }, | |
| { | |
| schema: "iglu:io.sspinc.partner/partner/jsonschema/1-0-0", | |
| data: { | |
| key: "acme", | |
| env: "prd" | |
| } | |
| }, | |
| ]; | |
| event.data.checkout.lineItems.forEach((lineItem) => { | |
| snowplow('trackSelfDescribingEvent', { | |
| event: { | |
| schema: 'iglu:io.sspinc.partner/visitor_ordered_variant/jsonschema/1-0-3', | |
| data: { | |
| variantId: lineItem.variant.id, | |
| productId: lineItem.variant.product.id, | |
| orderId: co.order.id, | |
| quantity: parseInt(lineItem.quantity), | |
| purchaseCurrency: lineItem.variant.price.currencyCode, | |
| purchasePrice: parseFloat(lineItem.variant.price.amount) | |
| } | |
| }, | |
| context: contexts | |
| }); | |
| }); | |
| }); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment