Stiddle Pixel Checkout Setup - Installing With Shopify 2.0 Using Customer Events

Installing The Stiddle Pixel With Checkout Using Customer Events

After adding the Stiddle Pixel to your theme.liquid website file (find article here), you'll need to install the Stiddle Pixel in checkout. Installing the Stiddle Pixel in checkout allows Stiddle to track conversions being made on site.

To get started, login to your Shopify account, then navigate to the "Settings" tab at the bottom left of your account.

Next, select the "Customer Events" tab, found on the left hand menu.

Select the "Add Custom Pixel" button.

 Then name the Pixel "Stiddle Pixel". Select "Add Pixel".

Under "Customer Privacy", select the "Permission" and "Data Sale" dropdown. 

Select "Not Required" option for "Permission" dropdown and "Data collected does not qualify as data sale" for "Data Sale" dropdown.

Next, copy and delete the existing commented out code under the "Code" section.

Copy the following code template below and paste the API key found at the beginning of the template below with the API key found within your Stiddle account - this can be found under "Pixel Settings" - see steps below to find. 

Copy the below Pixel script and replace with your Stiddle API key.

const apiKey="PASTE YOUR STIDDLE API KEY HERE",DOMAIN="https://api.stiddle.com/api/v1/contacts/track",APP_URL="https://cloudflare-cors-anywhere.james-725.workers.dev/?"+encodeURIComponent("https://api.stiddle.com/api/v1/contacts/track");function loadScript(e,t){var a=document.createElement("script");a.type="text/javascript",a.src=e,a.onload=t,a.onreadystatechange=function(){"complete"===this.readyState&&t()},document.head.appendChild(a)}async function getSessionDetails(){let e=await browser.sessionStorage.getItem("session_id");if(e){let t=Date.now(),a=(t-Number(e))/1e3;if(a>28e3){let o=Date.now();return browser.sessionStorage.setItem("session_id",o),Number(o)}return Number(e)}{let r=Date.now();return browser.sessionStorage.setItem("session_id",r),Number(r)}}function generateRandomId(e){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",a="";for(let o=0;o<e;o++){let r=Math.floor(Math.random()*t.length);a+=t.charAt(r)}return a}function getDevices(e){let t=e?.context?.window?.innerWidth;return t<768?"Mobile":t>=768&&t<992?"Tablet":"Desktop"}async function getIpAddress(){var e={method:"GET",redirect:"follow"};return new Promise(async(t,a)=>{await fetch("https://ipapi.co/json",e).then(e=>e.json()).then(e=>{t({ip:e.ip,location:{...e,platform:navigator.userAgent,os:navigator.platform}})}).catch(e=>{console.log("error",e),a(null)})})}const extractParamsFromUrl=e=>{let t=decodeURIComponent(e?.context?.window?.location?.href),a=new URL(t),o=new URLSearchParams(a.search),r={};for(let n of o.keys())r[n]=o.getAll(n);return r},commonKeys={stiddleID:"stiddleId",eventId:"eventId",contact_email:"c_email",cartToken:"cartToken",visit:"visit",click:"click",loadContent:"DOMContentLoaded",submit:"form_submit",socket:"socket"};class EventTracker{constructor(){this.serverUrl=APP_URL}createNewEventId(){let e=generateRandomId(10);return browser.localStorage.setItem(commonKeys.eventId,e),e}getEventId(){return browser.localStorage.getItem(commonKeys.eventId)}async generateEventPayload(e){return e?.data?.checkout,{eventType:commonKeys.visit,content:e.context?.window?.location?.host,shop:e.context?.window?.location?.host,checkout:getCheckoutDetails(e),uId:await eventTracker.getKeysFromLocalstorage(commonKeys.stiddleID),cartToken:await eventTracker.getKeysFromLocalstorage(commonKeys.cartToken),pageUrl:e?.context?.window?.location?.href,triggeredAt:Date(),session:await getSessionDetails(),referrer:"https://"+e.context?.window?.location?.host+"/",device:getDevices(e),event_time:e?.timestamp,apiKey}}async createEvent(e){this.passEvents({...await this.generateEventPayload(e),event_id:this.createNewEventId()},e)}passEvents(e,t){let a={...e};if(e?.uId)this.requestToServer(a,t);else{let o=Date.now().toString(36)+Math.random().toString(36).substr(2);this.createAndSaveNewStiddleID(o),this.requestToServer({...a,uId:o},t)}}async retriveUtmParams(e){let t=extractParamsFromUrl(e);if(Object.keys(t).length)await browser.localStorage.setItem("utm_params",JSON.stringify(t));else try{let a=await browser.localStorage.getItem("utm_params");if(a)return JSON.parse(a)}catch(o){console.error("Error retrieving UTM params:",o)}return t}async requestToServer(e,t){try{let a=await getIpAddress(),o={...e,cartItems:0,cartData:init.data.cart,utmParams:await this.retriveUtmParams(t),pathname:t?.context?.document?.location?.pathname,c_email:await browser.localStorage.getItem(commonKeys.contact_email),...a},r="https://"+t?.context?.window?.location?.host;var n=new XMLHttpRequest;n.open("POST",APP_URL),n.setRequestHeader("Content-Type","application/json;charset=UTF-8"),n.setRequestHeader("Access-Control-Allow-Origin",r),n.onload=function(){let e=JSON.parse(this.response);e&&e.data&&browser.localStorage.setItem(commonKeys.stiddleID,e.data)},n.send(JSON.stringify(o))}catch(s){console.log(s)}}async getKeysFromLocalstorage(e){let t=await browser.localStorage.getItem(e);return t}createAndSaveNewStiddleID(e){browser.localStorage.setItem(commonKeys.stiddleID,e)}async passSocketEvents(e){let t=await io("https://apptesting-tracking.stiddle.com");t.emit("contact-event",e)}}const eventTracker=new EventTracker;class FormSubmissions{retriveForms(){let e=document.getElementsByTagName("form");for(let t=0;t<e.length;t++){let a=e[t];a.addEventListener("submit",e=>{e.preventDefault(),this.retriveFormsData(e)})}}async retriveFormsData(e){let t=e.target,a=new FormData(t),o={selector_id:t.id};for(let r of a.keys())!r.includes("password")&&(o[r.toLowerCase()]=a.get(r));eventTracker.passEvents({eventType:commonKeys.submit,content:window.location.href,uId:await eventTracker.getKeysFromLocalstorage(commonKeys.stiddleID),pageUrl:window.location.href,triggeredAt:Date(),shop:window.location.hostname,session:await getSessionDetails(),formData:{...o,form_id:Date.now()},apiKey},e)}}const formSubmission=new FormSubmissions,stiddleAppTrackingInit=e=>{analytics.subscribe("checkout_completed",async e=>{await eventTracker.createEvent(e)})},getCheckoutDetails=e=>{let t=e?.data?.checkout;return t?(browser.localStorage.setItem(commonKeys.contact_email,t.email),{token:t.token,cart_token:eventTracker.getKeysFromLocalstorage(commonKeys.cartToken),order_id:t.order?.id,currency:t.currencyCode,total_price:t.totalPrice?.amount,total_tax:t.totalTax?.amount,discount:t.discountsAmount?.amount,customer:{email:t.email,phone:t.phone,first_name:t.billingAddress.firstName,last_name:t.billingAddress.lastName,country:t.billingAddress.country,country_code:t.billingAddress.countryCode,city:t.billingAddress.city,address:t.billingAddress.address1+" "+t.billingAddress.address2,province:t.billingAddress.province,province_code:t.billingAddress.provinceCode,zipCode:t.billingAddress.zip},items:t.lineItems.map(e=>({id:e.id,product_id:e.variant.product.id,name:e.title,price:e.finalLinePrice.amount,quantity:e.quantity,image:e.variant.image.src}))}):null};function modifyCartData(e){return e&&e.items&&e.items.length?e.items.map(e=>({name:e.title,image:e.image,price:e.price,final_price:e.final_price,quantity:e.quantity,product_id:e.product_id,total_discount:e.total_discount,total_price:e.final_line_price})):null}async function getCartItemsDetails(e){return e?new Promise((e,t)=>{fetch("/cart.js",{method:"GET"}).then(t=>{e(t.json())}).catch(e=>{t(e),console.error("Error:",e)})}):null}stiddleAppTrackingInit(apiKey);

Finding Your Stiddle API Key

To find your Stiddle API key navigate to your Stiddle account, hover over "Data" in the left hand menu, then select "Stiddle Pixel".

Copy the Stiddle Pixel code from Step 1, under "Base Code".

It will look something like this:

<script type="text/javascript" defer src='//tracking.stiddlepixel.com/' id="stiddle-script" apiKey="fec3cfd1-e8c1-463b-b42a-02e8f76f8cf1"></script>

Copy the "apiKey" from your Stiddle Pixel code.

Lastly, paste your Stiddle API key into the Stiddle Pixel Checkout Script template. Make sure not to remove the quotation marks within the script - copy and paste only the API key digits.

It will look something like this. 

const apiKey="fec3cfd1-e8c1-463b-b42a-02e8f76f8cf1",DOMAIN="https://api.stiddle.com/api/v1/contacts/track",APP_URL="https://cloudflare-cors-anywhere.james-725.workers.dev/?"+encodeURIComponent("https://api.stiddle.com/api/v1/contacts/track");function loadScript(e,t){var a=document.createElement("script");a.type="text/javascript",a.src=e,a.onload=t,a.onreadystatechange=function(){"complete"===this.readyState&&t()},document.head.appendChild(a)}async function getSessionDetails(){let e=await browser.sessionStorage.getItem("session_id");if(e){let t=Date.now(),a=(t-Number(e))/1e3;if(a>28e3){let o=Date.now();return browser.sessionStorage.setItem("session_id",o),Number(o)}return Number(e)}{let r=Date.now();return browser.sessionStorage.setItem("session_id",r),Number(r)}}function generateRandomId(e){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",a="";for(let o=0;o<e;o++){let r=Math.floor(Math.random()*t.length);a+=t.charAt(r)}return a}function getDevices(e){let t=e?.context?.window?.innerWidth;return t<768?"Mobile":t>=768&&t<992?"Tablet":"Desktop"}async function getIpAddress(){var e={method:"GET",redirect:"follow"};return new Promise(async(t,a)=>{await fetch("https://ipapi.co/json",e).then(e=>e.json()).then(e=>{t({ip:e.ip,location:{...e,platform:navigator.userAgent,os:navigator.platform}})}).catch(e=>{console.log("error",e),a(null)})})}const extractParamsFromUrl=e=>{let t=decodeURIComponent(e?.context?.window?.location?.href),a=new URL(t),o=new URLSearchParams(a.search),r={};for(let n of o.keys())r[n]=o.getAll(n);return r},commonKeys={stiddleID:"stiddleId",eventId:"eventId",contact_email:"c_email",cartToken:"cartToken",visit:"visit",click:"click",loadContent:"DOMContentLoaded",submit:"form_submit",socket:"socket"};class EventTracker{constructor(){this.serverUrl=APP_URL}createNewEventId(){let e=generateRandomId(10);return browser.localStorage.setItem(commonKeys.eventId,e),e}getEventId(){return browser.localStorage.getItem(commonKeys.eventId)}async generateEventPayload(e){return e?.data?.checkout,{eventType:commonKeys.visit,content:e.context?.window?.location?.host,shop:e.context?.window?.location?.host,checkout:getCheckoutDetails(e),uId:await eventTracker.getKeysFromLocalstorage(commonKeys.stiddleID),cartToken:await eventTracker.getKeysFromLocalstorage(commonKeys.cartToken),pageUrl:e?.context?.window?.location?.href,triggeredAt:Date(),session:await getSessionDetails(),referrer:"https://"+e.context?.window?.location?.host+"/",device:getDevices(e),event_time:e?.timestamp,apiKey}}async createEvent(e){this.passEvents({...await this.generateEventPayload(e),event_id:this.createNewEventId()},e)}passEvents(e,t){let a={...e};if(e?.uId)this.requestToServer(a,t);else{let o=Date.now().toString(36)+Math.random().toString(36).substr(2);this.createAndSaveNewStiddleID(o),this.requestToServer({...a,uId:o},t)}}async retriveUtmParams(e){let t=extractParamsFromUrl(e);if(Object.keys(t).length)await browser.localStorage.setItem("utm_params",JSON.stringify(t));else try{let a=await browser.localStorage.getItem("utm_params");if(a)return JSON.parse(a)}catch(o){console.error("Error retrieving UTM params:",o)}return t}async requestToServer(e,t){try{let a=await getIpAddress(),o={...e,cartItems:0,cartData:init.data.cart,utmParams:await this.retriveUtmParams(t),pathname:t?.context?.document?.location?.pathname,c_email:await browser.localStorage.getItem(commonKeys.contact_email),...a},r="https://"+t?.context?.window?.location?.host;var n=new XMLHttpRequest;n.open("POST",APP_URL),n.setRequestHeader("Content-Type","application/json;charset=UTF-8"),n.setRequestHeader("Access-Control-Allow-Origin",r),n.onload=function(){let e=JSON.parse(this.response);e&&e.data&&browser.localStorage.setItem(commonKeys.stiddleID,e.data)},n.send(JSON.stringify(o))}catch(s){console.log(s)}}async getKeysFromLocalstorage(e){let t=await browser.localStorage.getItem(e);return t}createAndSaveNewStiddleID(e){browser.localStorage.setItem(commonKeys.stiddleID,e)}async passSocketEvents(e){let t=await io("https://apptesting-tracking.stiddle.com");t.emit("contact-event",e)}}const eventTracker=new EventTracker;class FormSubmissions{retriveForms(){let e=document.getElementsByTagName("form");for(let t=0;t<e.length;t++){let a=e[t];a.addEventListener("submit",e=>{e.preventDefault(),this.retriveFormsData(e)})}}async retriveFormsData(e){let t=e.target,a=new FormData(t),o={selector_id:t.id};for(let r of a.keys())!r.includes("password")&&(o[r.toLowerCase()]=a.get(r));eventTracker.passEvents({eventType:commonKeys.submit,content:window.location.href,uId:await eventTracker.getKeysFromLocalstorage(commonKeys.stiddleID),pageUrl:window.location.href,triggeredAt:Date(),shop:window.location.hostname,session:await getSessionDetails(),formData:{...o,form_id:Date.now()},apiKey},e)}}const formSubmission=new FormSubmissions,stiddleAppTrackingInit=e=>{analytics.subscribe("checkout_completed",async e=>{await eventTracker.createEvent(e)})},getCheckoutDetails=e=>{let t=e?.data?.checkout;return t?(browser.localStorage.setItem(commonKeys.contact_email,t.email),{token:t.token,cart_token:eventTracker.getKeysFromLocalstorage(commonKeys.cartToken),order_id:t.order?.id,currency:t.currencyCode,total_price:t.totalPrice?.amount,total_tax:t.totalTax?.amount,discount:t.discountsAmount?.amount,customer:{email:t.email,phone:t.phone,first_name:t.billingAddress.firstName,last_name:t.billingAddress.lastName,country:t.billingAddress.country,country_code:t.billingAddress.countryCode,city:t.billingAddress.city,address:t.billingAddress.address1+" "+t.billingAddress.address2,province:t.billingAddress.province,province_code:t.billingAddress.provinceCode,zipCode:t.billingAddress.zip},items:t.lineItems.map(e=>({id:e.id,product_id:e.variant.product.id,name:e.title,price:e.finalLinePrice.amount,quantity:e.quantity,image:e.variant.image.src}))}):null};function modifyCartData(e){return e&&e.items&&e.items.length?e.items.map(e=>({name:e.title,image:e.image,price:e.price,final_price:e.final_price,quantity:e.quantity,product_id:e.product_id,total_discount:e.total_discount,total_price:e.final_line_price})):null}async function getCartItemsDetails(e){return e?new Promise((e,t)=>{fetch("/cart.js",{method:"GET"}).then(t=>{e(t.json())}).catch(e=>{t(e),console.error("Error:",e)})}):null}stiddleAppTrackingInit(apiKey);

Lastly, paste the entire Stiddle Pixel script in Shopify.

Be sure to click "Save" at the top of your screen, then click "Connect" below.

If you need any help installing the script, please click the "Book an Onboarding Call" button within your "Getting Started" page in your Stiddle account or message your account manage in Slack.

Was this article helpful?

How to send conversion data from Shopify to Meta & Google Ads - Stiddle's Setup Guide
Setup Stiddle Pixel With A NextJS Headless Shopify Store