Growify’s Shopify integration allows you to track customer events and gain deeper insights into your store’s performance. Follow these steps to create and set up a custom pixel for tracking.
1. Add Shopify Store
To connect your Shopify store to Growify simply head to the Shopify App Store and install our official Growify App.
2. Create a Custom Pixel
To start tracking events, you need to create a custom pixel in Shopify.
Please select the correct guide based on your version of Shopify. If you are already using Shopify Checkout Extensibility, please follow the instructions below.
But if you are still using the Legacy Checkout page and have not yet migrated to Checkout Extensibility, please use Legacy Checkout Guide
Go to Shopify Admin → Click Settings.
Navigate to Customer Events.
Click Add Custom Pixel.
In the pop-up window, enter a Pixel Name (e.g., growify-pixel).
Click Add Pixel to create it.
3. Set Up the Pixel
Set Permissions: Ensure that the "Not Required" checkbox is selected.
Copy the Growify Custom Pixel Script (see script below).
(()=>{var STORE_ID="ENTER_WORKSPACE_ID_HERE";var Cookie={prefix:function(){return"__grp_"},set:function(name,value,days=365){const expires=new Date(Date.now()+days*864e5).toUTCString();document.cookie=this.prefix()+name+"="+encodeURIComponent(value)+"; expires="+expires+"; path=/; SameSite=Lax"},get:function(name){const key=this.prefix()+name+"=";const cookies=document.cookie.split(";");for(let cookie of cookies){cookie=cookie.trim();if(cookie.indexOf(key)===0){return decodeURIComponent(cookie.substring(key.length))}}return""},delete:function(name){this.set(name,"",-1)},exists:function(name){return this.get(name)!==""},setUTMs:function(){const params=new URLSearchParams(window.location.search);const utms={};const utmKeys=["utm_source","utm_medium","utm_campaign","utm_term","utm_content","utm_source_platform","utm_creative_format","utm_marketing_tactic"];let anyFound=false;for(const key of utmKeys){const value=params.get(key);if(value){utms[key]=value;anyFound=true}}if(anyFound){this.set("utm",JSON.stringify(utms))}},getUTM:function(key){if(this.exists("utm")){const utms=JSON.parse(this.get("utm"));return utms[key]||""}return""}};var Fingerprint={get:function(){const navigatorInfo=navigator.userAgent;const screenInfo=window.screen.width+"x"+window.screen.height+"x"+window.screen.colorDepth;const timezone=new Date().getTimezoneOffset();return btoa(navigatorInfo+screenInfo+timezone)}};var Helper={now:function(){return Math.floor(Date.now()/1e3)},utmMap:{utm_source:["gr_source","tw_source","utm_source"],utm_campaign:["gr_campaign","tw_campaign","fbc_id","fb_campaignid","utm_campaign"],utm_medium:["utm_medium"],utm_term:["gr_term","fb_adsetid","utm_term"],utm_content:["gr_content","utm_content"],utm_adid:["gr_gadid","tw_adid","h_ad_id","fb_adid","gr_fbadid","utm_id"]},parseUTMs:function(){const params=new URLSearchParams(window.location.search);const utms={};Object.keys(this.utmMap).forEach(key=>{let found=false;for(const altKey of this.utmMap[key]){const value=params.get(altKey);if(value){utms[key]=value;found=true;break}}if(!found){const cookieValue=Cookie.getUTM(key);utms[key]=cookieValue||""}});return utms},grabOrderDataIfAny:function(){if(window.Shopify&&window.Shopify.checkout){return{order_id:window.Shopify.checkout.order_id,total_price:window.Shopify.checkout.total_price,currency:window.Shopify.checkout.currency,line_items:window.Shopify.checkout.line_items,customer:window.Shopify.checkout.customer}}return null},async domainName(url){const commonTLDs=["com","org","net","gov","edu","co","io","ac","biz","info","mobi","pro","name","shop","club","uk","us","eu","ca","au","pk","de","fr","it","es","in","nl","ru","br","jp","ch","se","no","be","at","dk","fi","za","nz","mx","ar","pl","id","ie","sg","my","gr","pt","hk","il","ph","vn","tr","si","cz","sk","lt","lv","ee","uy","bg","hr","tw","ro","is","hu","rs","lu","vn","ma","ba","ua","kr","cn","ae","qa","ng","pe","app","online","site","store","tech","blog","xyz","design","art","ai",""];const _url=new URL(url);const hostname=_url.hostname.replace("www.","");const domainParts=hostname.split(".");let domainIndex=-1;for(let i=domainParts.length-1;i>=0;i--){if(!commonTLDs.includes(domainParts[i].toLowerCase())){domainIndex=i;break}}return domainIndex>=0?domainParts[domainIndex]:domainParts[0]},async fuzzySourceDetection(source,url){const fb=["Facebook","facebook","Facebook_Ad","Facebook_Ads","facebook_Ad","Facebook_ads","facebook_ad","fb","Fb","Ig","ig","Fb_ig","fb_ig","Fb/ig","fb/ig","Instagram","instagram","IGShopping","igshopping"];const tiktok=["tiktok","tt","tiktok_ads","tiktokads","tiktok_ad","tiktokads"];const google=["google","gads","google_ads","google_ad","googleads","googlead"];source=(source||"").toLowerCase();if(fb.includes(source)||url.includes("fbclid")){return"facebook"}if(tiktok.includes(source)||url.includes("ttclid")){return"tiktok"}if(google.includes(source)||url.includes("gclid")){return"google"}return source},async detectSourceSmartly(){const utms=this.parseUTMs();let source=utms.utm_source;if(source){return await this.fuzzySourceDetection(source,window.location.href)}if(document.referrer){const domain2=await this.domainName(document.referrer);return await this.fuzzySourceDetection(domain2,document.referrer)}const domain=await this.domainName(window.location.href);return await this.fuzzySourceDetection(domain,window.location.href)},getBrowserNameAndVersion:function(){const ua=navigator.userAgent;let tem;let M=ua.match(/(opera|chrome|safari|firefox|msie|trident)\/?\s*(\d+)/i)||[];if(/trident/i.test(M[1])){tem=/\brv[ :]+(\d+)/g.exec(ua)||[];return"IE "+(tem[1]||"")}if(M[1]==="Chrome"){tem=ua.match(/\b(OPR|Edge)\/(\d+)/);if(tem!=null){return tem.slice(1).join(" ").replace("OPR","Opera")}}M=M[2]?[M[1],M[2]]:[navigator.appName,navigator.appVersion,"-?"];if((tem=ua.match(/version\/(\d+)/i))!=null){M.splice(1,1,tem[1])}return M.join(" ")},isMobileDevice:function(){return"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0},getUserAgent:function(){return navigator.userAgent}};var Validator={validateConversionDTO(dto){const errors=[];const hasValue=typeof dto.value==="number";const hasProducts=Array.isArray(dto.products)&&dto.products.length>0&&dto.products.every(p=>typeof p.productQuantity==="number"&&p.productQuantity>0&&typeof p.purchaseValue==="number"&&p.purchaseValue>0);if(!hasValue&&!hasProducts){errors.push("Conversion DTO must include either value or a valid products array.")}return errors}};Cookie.setUTMs();var script=document.currentScript||document.querySelector("script[data-website-id]");var ENDPOINT_MAP={api_v2:"https://us-central1-growify-346505.cloudfunctions.net/grpV2"};var Config={id:script?.getAttribute("data-website-id")||STORE_ID||null,endpointKey:script?.getAttribute("data-endpoint")||"api_v2",version:"1.0.0",platform:script?.getAttribute("data-platform")||"web",params:{}};if(!Config.id){console.error("GRP: Missing website id. Use <script data-website-id=xxx>")}function resolveEndpoint(){return ENDPOINT_MAP[Config.endpointKey]||Config.endpointKey}function getVisitorId(){let visitorId=Cookie.get("grp_uid");if(!visitorId){visitorId=Fingerprint.get();Cookie.set("grp_uid",visitorId)}return visitorId}async function buildPayload(eventName,optionalData={}){const utms=Helper.parseUTMs();const source=await Helper.detectSourceSmartly();let ed="";if(typeof optionalData==="object"){ed=JSON.stringify(optionalData)}else{ed=optionalData}return{id:Config.id,uid:getVisitorId(),ev:eventName,ed,v:Config.version,platform:Config.platform,source,dl:window.location.href,rl:document.referrer,ts:Helper.now(),de:document.characterSet,sr:window.screen.width+"x"+window.screen.height,vp:window.innerWidth+"x"+window.innerHeight,cd:window.screen.colorDepth,dt:document.title,bn:Helper.getBrowserNameAndVersion(),md:Helper.isMobileDevice()?"true":"false",ua:Helper.getUserAgent(),tz:new Date().getTimezoneOffset(),gaid:(document.cookie.match(/_ga=([^;]+)/)||[])[1]||"",fbid:(document.cookie.match(/_fbp=([^;]+)/)||[])[1]||"",gr_user_id:getVisitorId(),utm_source:utms.utm_source||"",utm_medium:utms.utm_medium||"",utm_campaign:utms.utm_campaign||"",utm_term:utms.utm_term||"",utm_content:utms.utm_content||"",utm_source_platform:utms.utm_source_platform||"",utm_creative_format:utms.utm_creative_format||"",utm_marketing_tactic:utms.utm_marketing_tactic||"",...Config.params}}async function sendEvent(eventName,optionalData){const payload=await buildPayload(eventName,optionalData);const endpoint=resolveEndpoint();const blob=new Blob([JSON.stringify(payload)],{type:"application/json"});const beaconSuccess=navigator.sendBeacon(endpoint,blob);if(!beaconSuccess){console.warn("\u2757 sendBeacon failed, falling back to fetch...");fetch(endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload)}).catch(err=>console.error("\u2757 Fetch fallback failed:",err))}else{console.log("\u2705 GRP Event sent: "+eventName)}}window.addEventListener("load",()=>{sendEvent("pageload")});window.addEventListener("beforeunload",()=>{sendEvent("pageclosed")});window.grp=function(command,data){console.log("[GRP] Called with:",command,data);if(command==="conversion"){const errors=Validator.validateConversionDTO(data);if(errors.length){errors.forEach(error=>console.error(error));return}sendEvent("purchase",data)}if(command==="lead-generated"){const product=[{productName:"Lead Generated",purchaseValue:1}];const payload={...data,products:product};sendEvent("purchase",payload)}if(command==="init"){Config.id=data}if(command==="event"&&data?.name){console.log("Got event: ",data.name);sendEvent(data.name,data.payload||{})}};if(Array.isArray(window.grpQueue)){for(const args of window.grpQueue){try{window.grp.apply(null,args)}catch(error){console.error("Failed to replay queued grp call:",error)}}window.grpQueue=[]}if(typeof analytics!=="undefined"&&typeof analytics.subscribe==="function"){try{analytics.subscribe("page_viewed",event=>{sendEvent("pageload");console.log("\u2705 Shopify pageload"+event)});analytics.subscribe("payment_info_submitted",event=>{sendEvent("payment_info_submitted");console.log("\u2705 Shopify payment_info_submitted "+event)});analytics.subscribe("checkout_started",event=>{sendEvent("checkout_started");console.log("\u2705 Shopify Conversion Started "+event)});analytics.subscribe("checkout_completed",event=>{const products=[];const lineItems=((event.data||{}).checkout||{}).lineItems||[];for(let product of lineItems){const{variant={},quantity=0,finalLinePrice={}}=product||{};products.push({productId:((variant||{}).product||{}).id||"",productName:((variant||{}).product||{}).title||"",productPrice:((variant||{}).price||{}).amount||0,productBrand:((variant||{}).price||{}).vendor||"",productQuantity:quantity||0,purchaseValue:finalLinePrice.amount||0})}const checkout=(event.data||{}).checkout||{};const{order={},email="",billingAddress={},totalTax={}}=checkout;const payload={orderId:(order||{}).id||"",userId:((order||{}).customer||{}).id||"",userEmail:email||"",userFirstName:billingAddress.firstName||"",userLastName:billingAddress.lastName||"",tax:totalTax.amount||0,products};sendEvent("purchase",payload);console.log("\u2705 Shopify Conversion complete ended "+event)})}catch(err){console.warn("Shopify Customer Events subscription failed:",err)}}})();
Paste the script into the Code section.
Click Save to apply the changes.
If the setup is valid, the Connect button will become active. Click Connect to activate the script and start collecting events.