{"id":16282,"date":"2026-06-15T02:49:19","date_gmt":"2026-06-15T06:49:19","guid":{"rendered":"https:\/\/www.palamsolutions.com\/blog\/?p=16282"},"modified":"2026-06-15T03:00:54","modified_gmt":"2026-06-15T07:00:54","slug":"shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup","status":"publish","type":"post","link":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/","title":{"rendered":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"16282\" class=\"elementor elementor-16282\">\n\t\t\t\t<div class=\"elementor-element elementor-element-53cba11 e-flex e-con-boxed e-con e-parent\" data-id=\"53cba11\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ab982c8 elementor-widget elementor-widget-text-editor\" data-id=\"ab982c8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>If you&#8217;re running a Shopify store and spending money on Meta Ads or Google Ads, you&#8217;re probably losing a significant amount of conversion data without even realizing it.<\/p><p>iOS 14+ changed everything. Apple&#8217;s App Tracking Transparency framework caused Meta Pixel to miss anywhere between 40\u201360% of conversions. Add browser-based ad blockers and cookie restrictions, and your campaign data becomes increasingly unreliable \u2014 leading to poor algorithmic optimization and wasted ad spend.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d0d3d50 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"d0d3d50\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3f57f2c elementor-widget elementor-widget-text-editor\" data-id=\"3f57f2c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>The solution is Server-Side Tracking.<\/h2><p>In this guide, I&#8217;ll walk you through exactly how we set up a complete server-side tracking system on a Shopify Basic plan \u2014 using\u00a0 <strong>Cloudflare Workers (free)<\/strong>\u00a0 as the middleware \u2014 to send accurate Purchase events to both\u00a0 <strong>Meta Conversions API<\/strong>\u00a0 and\u00a0 <strong>GA4 Measurement Protocol<\/strong>.<\/p><p>No paid servers. No complex infrastructure. Just free tools working together.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-318dd37 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"318dd37\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0623ba2 elementor-widget elementor-widget-text-editor\" data-id=\"0623ba2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Why Browser-Based Tracking Is Failing<\/h2>\n<ol>\n<li><strong>iOS 14+ Privacy Changes<\/strong><br>\nApple&#8217;s ATT prompt allows users to opt out of cross-app tracking. This caused Meta Pixel accuracy to drop dramatically overnight for most advertisers.\n<\/li>\n<li><strong>Ad Blockers<\/strong><br>\nStudies suggest over 30% of internet users run ad blockers, which completely block browser-based pixels from firing.\n<\/li>\n<li><strong>Cookie Restrictions<\/strong><br>\nSafari already blocks third-party cookies. Firefox does too. Chrome is following. This means `_fbp` and `_ga` cookies have shorter lifespans and reduced accuracy.\n<\/li>\n<li><strong>The Draft Orders Problem<\/strong><br>\nA very common issue with Shopify&#8217;s native Facebook &amp; Instagram app \u2014 it tracks draft orders as Purchase events, sending false conversion signals to Meta and inflating your reported ROAS.\n<\/li>\n<\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5823df5 e-flex e-con-boxed e-con e-parent\" data-id=\"5823df5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3522730 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"3522730\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c3b4b7c elementor-widget elementor-widget-text-editor\" data-id=\"c3b4b7c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>The Architecture<\/h2>\nHere&#8217;s the full picture of how everything connects:\n<pre>\n<code>\nCustomer visits store\n\u2193\ntheme.liquid runs on every page\n\u2192 Captures GA4 Client ID (_ga cookie)\n\u2192 Captures Meta FBP \/ FBC cookies\n\u2192 Captures UTM parameters from URL\n\u2192 Saves everything to cart attributes\n\u2193\nCustomer completes checkout\n\u2193\nShopify automatically copies cart attributes\ninto order note_attributes\n\u2193\nShopify fires \"Order Payment\" Webhook\n\u2193\nCloudflare Worker receives the webhook\n\u2192 Filters: only paid + web orders pass\n\u2192 Reads note_attributes (GA4 ID, FBP, UTMs)\n\u2192 SHA256 hashes customer PII\n\u2192 Calls Meta CAPI\n\u2192 Calls GA4 Measurement Protocol\n\u2193\nMeta Ads Manager \u2705   Google Analytics \u2705\n<\/code>\n<\/pre>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e81ce81 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"e81ce81\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b1e189c elementor-widget elementor-widget-text-editor\" data-id=\"b1e189c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Tools Used (All Free)<\/h2><p>\u00a0<\/p><table><thead><tr><th>Tool<\/th><th>Purpose<\/th><th>Cost<\/th><\/tr><\/thead><tbody><tr><td>Cloudflare Workers<\/td><td>Run server-side code<\/td><td>Free (100k req\/day)<\/td><\/tr><tr><td>Meta Conversions API<\/td><td>Server-side purchase tracking<\/td><td>Free<\/td><\/tr><tr><td>GA4 Measurement Protocol<\/td><td>Server-side GA4 events<\/td><td>Free<\/td><\/tr><tr><td>Shopify Webhooks<\/td><td>Receive order events<\/td><td>Free on Basic plan<\/td><\/tr><tr><td>Shopify theme.liquid<\/td><td>Capture browser-side data<\/td><td>Free<\/td><\/tr><\/tbody><\/table>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c399d0f elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"c399d0f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8489e77 elementor-widget elementor-widget-text-editor\" data-id=\"8489e77\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Step 1 \u2014 Capture Browser Data (theme.liquid)<\/h2><p>The biggest challenge with server-side tracking is that some data only exists in the browser:<\/p><ul><li><strong>GA4 Client ID<\/strong>stored in the `_ga` cookie<\/li><li><strong>Meta FBP<\/strong>stored in the `_fbp` cookie<\/li><li><strong>Meta FBC<\/strong>stored in the `_fbc` cookie (built from `fbclid` URL parameter)<\/li><li><strong>UTM Parameters<\/strong>only present in the URL on the landing page visit<\/li><\/ul><p>Shopify has a powerful built-in feature:\u00a0 cart attributes are automatically copied into order <code>`note_attributes`<\/code>\u00a0 when a customer checks out. We use this to bridge browser data to the server.<\/p><p>Add the following code to `theme.liquid`\u00a0 just before the <code>`&lt;\/head&gt;`<\/code> tag:<\/p><p><strong>Shopify Admin \u2192 Online Store \u2192 Themes \u2192 Edit Code \u2192 theme.liquid<\/strong><\/p><pre><code>\nhtml\n&lt;script&gt;\n(function() {\nfunction getCookieMatch(pattern) {\nvar m = document.cookie.match(pattern);\nreturn m ? String(m[1]) : null;\n}\n\n\/\/ GA4 Client ID from _ga cookie\nvar clientId = getCookieMatch(\/_ga=GA\\d+\\.\\d+\\.(\\d+\\.\\d+)\/);\n\n\/\/ Meta FBP and FBC cookies\nvar fbp = getCookieMatch(\/_fbp=(fb\\.\\d+\\.\\d+\\.\\d+)\/);\nvar fbc = getCookieMatch(\/_fbc=(fb\\.[^;]+)\/);\n\n\/\/ UTM parameters \u2014 only available on landing page\n\/\/ Save to sessionStorage so they persist through checkout\nvar params = new URLSearchParams(window.location.search);\nif (params.get('utm_source')) {\nsessionStorage.setItem('utm_source', params.get('utm_source') || '');\nsessionStorage.setItem('utm_medium', params.get('utm_medium') || '');\nsessionStorage.setItem('utm_campaign', params.get('utm_campaign') || '');\nsessionStorage.setItem('utm_content', params.get('utm_content') || '');\nsessionStorage.setItem('utm_term', params.get('utm_term') || '');\nsessionStorage.setItem('utm_id', params.get('utm_id') || '');\n}\n\nvar attrs = {};\nvar ss = sessionStorage;\n\nif (clientId) attrs.ga4_client_id = clientId;\nif (fbp) attrs._fbp = fbp;\nif (fbc) attrs._fbc = fbc;\nif (ss.getItem('utm_source')) attrs.utm_source = ss.getItem('utm_source');\nif (ss.getItem('utm_medium')) attrs.utm_medium = ss.getItem('utm_medium');\nif (ss.getItem('utm_campaign')) attrs.utm_campaign = ss.getItem('utm_campaign');\nif (ss.getItem('utm_content')) attrs.utm_content = ss.getItem('utm_content');\nif (ss.getItem('utm_term')) attrs.utm_term = ss.getItem('utm_term');\nif (ss.getItem('utm_id')) attrs.utm_id = ss.getItem('utm_id');\n\nif (Object.keys(attrs).length === 0) return;\n\n\/\/ Save to cart attributes\nfetch('\/cart\/update.js', {\nmethod: 'POST',\nheaders: { 'Content-Type': 'application\/json' },\nbody: JSON.stringify({ attributes: attrs })\n});\n})();\n&lt;\/script&gt;\n<\/code><\/pre><h3>How this Works<\/h3><ol><li>Script runs on every page load.<\/li><li>Reads cookies and UTM parameters from the browser.<\/li><li>UTM values are stored in <code>sessionStorage<\/code> so they persist across page navigation.<\/li><li>All attribution data is pushed to cart attributes using <code>\/cart\/update.js<\/code>.<\/li><li>When the customer completes checkout, Shopify automatically copies the cart attributes to <code>order.note_attributes<\/code>.<\/li><li>The Cloudflare Worker receives the order webhook and reads the attribution data from the webhook payload.<\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cfead8f elementor-alert-info elementor-widget elementor-widget-alert\" data-id=\"cfead8f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"alert.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-alert\" role=\"alert\">\n\n\t\t\t\t\t\t<span class=\"elementor-alert-title\">Important note about Shopify Custom Pixels:<\/span>\n\t\t\t\n\t\t\t\t\t\t<span class=\"elementor-alert-description\">We initially tried implementing this via a Shopify Custom Pixel. However, Custom Pixels run inside a sandboxed iframe and cannot make same-origin requests to `\/cart\/update.js`. The `theme.liquid` approach is the correct solution.\n<\/span>\n\t\t\t\n\t\t\t\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f171994 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"f171994\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7ead5fe elementor-widget elementor-widget-text-editor\" data-id=\"7ead5fe\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Step 2 \u2014 Set Up Cloudflare Worker<\/h2>\n&nbsp;\n<h3>2.1 Create a Free Account<\/h3>\nSign up at <a href=\"https:\/\/cloudflare.com\" target=\"_blank\" rel=\"noopener noreferrer\">cloudflare.com<\/a>.\nThe free plan includes up to 100,000 Worker requests per day, which is more than sufficient for most Shopify stores.\n<h3>2.2 Create the Worker<\/h3>\n<ol>\n \t<li>Go to <strong>Workers &amp; Pages \u2192 Create \u2192 Start with Hello World<\/strong>.<\/li>\n \t<li>Name the Worker: <code>shopify-tracking-worker<\/code>.<\/li>\n \t<li>Click <strong>Deploy<\/strong>.<\/li>\n \t<li>Open <strong>Edit Code<\/strong> and replace the default code with the following:<\/li>\n<\/ol>\n<h3>2.3 The Worker Code<\/h3>\n<pre><code>\nconst META_ACCESS_TOKEN = 'YOUR_META_ACCESS_TOKEN';\nconst META_PIXEL_ID = 'YOUR_PIXEL_ID';\nconst GA4_MEASUREMENT_ID = 'G-XXXXXXXXXX';\nconst GA4_API_SECRET = 'YOUR_GA4_API_SECRET';\n\nexport default {\nasync fetch(request, env) {\n\n\/\/ Handle CORS preflight\nif (request.method === 'OPTIONS') {\nreturn new Response(null, {\nheaders: {\n'Access-Control-Allow-Origin': '*',\n'Access-Control-Allow-Methods': 'POST',\n'Access-Control-Allow-Headers': 'Content-Type'\n}\n});\n}\n\nif (request.method !== 'POST') {\nreturn new Response('Method not allowed', { status: 405 });\n}\n\ntry {\nconst body = await request.json();\nconst order = body.order || body;\n\n\/\/ Filter 1: Only process paid orders\nif (order.financial_status !== 'paid') {\nreturn new Response(JSON.stringify({\nstatus: 'skipped',\nreason: `Order status: ${order.financial_status}`\n}), { headers: { 'Content-Type': 'application\/json', 'Access-Control-Allow-Origin': '*' } });\n}\n\n\/\/ Filter 2: Only process online orders\n\/\/ This blocks POS, draft orders, and admin-created orders\nif (order.source_name !== 'web') {\nreturn new Response(JSON.stringify({\nstatus: 'skipped',\nreason: `Non-web order skipped \u2014 source: ${order.source_name}`\n}), { headers: { 'Content-Type': 'application\/json', 'Access-Control-Allow-Origin': '*' } });\n}\n\n\/\/ Read note_attributes (captured from browser via cart attributes)\nconst attributes = order.note_attributes || [];\nconst getAttr = (key) =&gt; attributes.find(a =&gt; a.name === key)?.value || null;\n\nconst gaClientId = getAttr('ga4_client_id');\nconst fbp = getAttr('_fbp');\nconst fbc = getAttr('_fbc');\nconst utmSource = getAttr('utm_source');\nconst utmMedium = getAttr('utm_medium');\nconst utmCampaign = getAttr('utm_campaign');\nconst utmContent = getAttr('utm_content');\nconst utmTerm = getAttr('utm_term');\nconst utmId = getAttr('utm_id');\n\n\/\/ Customer and address data\nconst customer = order.customer || {};\nconst address = order.billing_address || order.shipping_address || {};\n\n\/\/ Fallback to shipping address for guest checkouts\nconst firstName = customer.first_name || address.first_name || '';\nconst lastName = customer.last_name || address.last_name || '';\nconst phone = customer.phone || address.phone || order.phone || '';\nconst email = customer.email || order.email || '';\nconst city = address.city || '';\nconst zip = address.zip || '';\nconst country = address.country_code || '';\n\n\/\/ SHA256 hashing \u2014 required by Meta for PII data\nasync function hashData(value) {\nif (!value) return null;\nconst clean = value.toString().toLowerCase().trim();\nconst buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(clean));\nreturn Array.from(new Uint8Array(buf)).map(b =&gt; b.toString(16).padStart(2, '0')).join('');\n}\n\nconst [hEmail, hPhone, hFname, hLname, hCity, hZip, hCountry] = await Promise.all([\nhashData(email), hashData(phone), hashData(firstName),\nhashData(lastName), hashData(city), hashData(zip),\ncountry ? hashData(country.toLowerCase()) : null\n]);\n\n\/\/ Line items\nconst lineItems = (order.line_items || []).map(item =&gt; ({\nitem_id: item.sku || String(item.variant_id),\nitem_name: item.title,\nprice: parseFloat(item.price),\nquantity: parseInt(item.quantity, 10)\n}));\n\n\/\/ GA4 Client ID \u2014 use captured value or generate fallback\nconst finalClientId = gaClientId ||\n`${Math.floor(1000000000 + Math.random() * 9000000000)}.${customer.id || order.id}`;\n\n\/\/ \u2500\u2500 META CONVERSIONS API PAYLOAD \u2500\u2500\nconst metaPayload = {\ndata: [{\nevent_name: 'Purchase',\nevent_time: Math.floor(Date.now() \/ 1000),\nevent_id: `purchase_${order.id}`, \/\/ For deduplication\naction_source: 'website',\nevent_source_url: 'https:\/\/your-store.myshopify.com',\nuser_data: {\n...(hEmail &amp;&amp; { em: [hEmail] }),\n...(hPhone &amp;&amp; { ph: [hPhone] }),\n...(hFname &amp;&amp; { fn: [hFname] }),\n...(hLname &amp;&amp; { ln: [hLname] }),\n...(hCity &amp;&amp; { ct: [hCity] }),\n...(hZip &amp;&amp; { zp: [hZip] }),\n...(hCountry &amp;&amp; { country: [hCountry] }),\n...(fbp &amp;&amp; { fbp }),\n...(fbc &amp;&amp; { fbc }),\n},\ncustom_data: {\ncurrency: order.currency || 'USD',\nvalue: parseFloat(order.total_price || 0),\norder_id: String(order.id),\ncontent_type: 'product',\ncontents: lineItems.map(i =&gt; ({\nid: i.item_id,\nquantity: i.quantity,\nitem_price: i.price\n}))\n}\n}],\naccess_token: META_ACCESS_TOKEN\n};\n\n\/\/ \u2500\u2500 GA4 MEASUREMENT PROTOCOL PAYLOAD \u2500\u2500\nconst ga4Payload = {\nclient_id: finalClientId,\n...(customer.id &amp;&amp; { user_id: String(customer.id) }),\nevents: [{\nname: 'purchase',\nparams: {\ntransaction_id: order.name, \/\/ e.g. #1234\nvalue: parseFloat(order.total_price || 0),\ncurrency: order.currency || 'USD',\ntax: parseFloat(order.total_tax || 0),\nshipping: parseFloat(order.shipping_lines?.[0]?.price || 0),\nengagement_time_msec: 1,\n...(utmId &amp;&amp; { campaign_id: utmId }),\n...(utmCampaign &amp;&amp; { campaign: utmCampaign }),\n...(utmSource &amp;&amp; { source: utmSource }),\n...(utmMedium &amp;&amp; { medium: utmMedium }),\n...(utmContent &amp;&amp; { content: utmContent }),\n...(utmTerm &amp;&amp; { term: utmTerm }),\nitems: lineItems\n}\n}]\n};\n\n\/\/ \u2500\u2500 SEND BOTH IN PARALLEL \u2500\u2500\nconst [metaRes, ga4Res] = await Promise.all([\nfetch(`https:\/\/graph.facebook.com\/v18.0\/${META_PIXEL_ID}\/events`, {\nmethod: 'POST',\nheaders: { 'Content-Type': 'application\/json' },\nbody: JSON.stringify(metaPayload)\n}),\nfetch(`https:\/\/www.google-analytics.com\/mp\/collect?measurement_id=${GA4_MEASUREMENT_ID}&amp;api_secret=${GA4_API_SECRET}`, {\nmethod: 'POST',\nheaders: { 'Content-Type': 'application\/json' },\nbody: JSON.stringify(ga4Payload)\n})\n]);\n\nconst metaResult = await metaRes.json();\nconsole.log('Meta Response:', JSON.stringify(metaResult));\nconsole.log('GA4 HTTP Status:', ga4Res.status); \/\/ 204 = success\n\nreturn new Response(JSON.stringify({\nstatus: 'success',\nmeta: metaResult,\nga4_status: ga4Res.status\n}), {\nheaders: { 'Content-Type': 'application\/json', 'Access-Control-Allow-Origin': '*' }\n});\n\n} catch (err) {\nconsole.error('Worker error:', err.message);\nreturn new Response(JSON.stringify({\nstatus: 'error',\nmessage: err.message\n}), {\nstatus: 500,\nheaders: { 'Content-Type': 'application\/json', 'Access-Control-Allow-Origin': '*' }\n});\n}\n}\n};\n<\/code><\/pre>\n\n<h2>Step 3 \u2014 Configure Shopify Webhook<\/h2>\n\n<p>\n    In your Shopify admin, navigate to:\n<\/p>\n\n<p>\n    <strong>Settings \u2192 Notifications \u2192 Webhooks \u2192 Create Webhook<\/strong>\n<\/p>\n\n<table>\n    <tbody>\n        <tr>\n            <th>Event<\/th>\n            <td>Order payment <em>(Critical: NOT &#8220;Order creation&#8221;)<\/em><\/td>\n        <\/tr>\n        <tr>\n            <th>Format<\/th>\n            <td>JSON<\/td>\n        <\/tr>\n        <tr>\n            <th>URL<\/th>\n            <td><code>https:\/\/your-worker.workers.dev<\/code><\/td>\n        <\/tr>\n    <\/tbody>\n<\/table>\n\n<p>\n    Using <strong>Order payment<\/strong> instead of <strong>Order creation<\/strong> is important because the webhook only fires after payment has been successfully confirmed. This helps filter out most draft, abandoned, and pending orders.\n<\/p>\n\n<hr>\n\n<h2>Step 4 \u2014 Get Your Meta Access Token<\/h2>\n\n<ol>\n    <li>Open <strong>Business Manager \u2192 Events Manager<\/strong>.<\/li>\n    <li>Select your Meta Pixel.<\/li>\n    <li>Click <strong>Settings \u2192 Generate Access Token<\/strong>.<\/li>\n    <li>Copy the generated token.<\/li>\n    <li>Paste the token into your Cloudflare Worker code.<\/li>\n<\/ol>\n\n<hr>\n\n<h2>Step 5 \u2014 Get Your GA4 API Secret<\/h2>\n\n<ol>\n    <li>Open <strong>Google Analytics \u2192 Admin \u2192 Data Streams<\/strong>.<\/li>\n    <li>Select your website data stream.<\/li>\n    <li>Navigate to <strong>Measurement Protocol API Secrets<\/strong>.<\/li>\n    <li>Click <strong>Create<\/strong>.<\/li>\n    <li>Provide a name for the secret and save it.<\/li>\n    <li>Copy the generated secret value.<\/li>\n    <li>Paste the secret into your Cloudflare Worker code.<\/li>\n<\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-66d6bae elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"66d6bae\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d79c534 elementor-widget elementor-widget-text-editor\" data-id=\"d79c534\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Key Technical Decisions Explained<\/h2>\n\n<h3>Why Filter by <code>source_name !== 'web'<\/code>?<\/h3>\n\n<p>\n    Shopify&#8217;s <code>order.source_name<\/code> field tells you exactly where an order originated.\n<\/p>\n\n<table>\n    <thead>\n        <tr>\n            <th>Value<\/th>\n            <th>Source<\/th>\n        <\/tr>\n    <\/thead>\n    <tbody>\n        <tr>\n            <td><code>web<\/code><\/td>\n            <td>Online Store \u2705<\/td>\n        <\/tr>\n        <tr>\n            <td><code>pos<\/code><\/td>\n            <td>Point of Sale<\/td>\n        <\/tr>\n        <tr>\n            <td><code>draft_orders<\/code><\/td>\n            <td>Draft Order<\/td>\n        <\/tr>\n        <tr>\n            <td><code>admin<\/code><\/td>\n            <td>Manually Created in Admin<\/td>\n        <\/tr>\n        <tr>\n            <td><code>580111<\/code><\/td>\n            <td>Facebook \/ Instagram Shop<\/td>\n        <\/tr>\n        <tr>\n            <td><code>755357713<\/code><\/td>\n            <td>Google Channel<\/td>\n        <\/tr>\n    <\/tbody>\n<\/table>\n\n<p>\n    By allowing only <code>web<\/code> orders, POS sales, draft orders, admin-created orders, and marketplace orders are excluded from purchase tracking. This prevents false conversion events from being sent to Meta and GA4.\n<\/p>\n\n<hr>\n\n<h3>Why SHA256 Hash Customer Data?<\/h3>\n\n<p>\n    Meta Conversions API requires personally identifiable information (PII) such as email addresses, phone numbers, names, and addresses to be hashed using SHA256 before transmission.\n<\/p>\n\n<p>\n    Hashing helps protect user privacy, aligns with Meta&#8217;s requirements, and supports GDPR best practices. Cloudflare Workers include the built-in <code>crypto.subtle<\/code> API, making it possible to generate SHA256 hashes without installing additional libraries.\n<\/p>\n\n<hr>\n\n<h3>How Does Deduplication Work?<\/h3>\n\n<p>\n    When both browser-side tracking and server-side tracking are active, the same purchase can be recorded twice unless a deduplication strategy is implemented.\n<\/p>\n\n<h4>Meta Conversions API<\/h4>\n\n<ul>\n    <li>Use the same event ID in both browser and server events.<\/li>\n    <li>Example: <code>purchase_123456789<\/code><\/li>\n    <li>Meta automatically merges matching events and removes duplicates.<\/li>\n<\/ul>\n\n<h4>Google Analytics 4<\/h4>\n\n<ul>\n    <li>Use the same <code>transaction_id<\/code> for browser and server events.<\/li>\n    <li>Typically this is the Shopify order number (for example, <code>#1234<\/code>).<\/li>\n    <li>GA4 automatically deduplicates purchases that share the same transaction ID.<\/li>\n<\/ul>\n\n<hr>\n\n<h3>Why Cart Attributes Instead of Checkout Extensibility?<\/h3>\n\n<p>\n    Shopify&#8217;s Checkout Extensibility framework restricts access to many checkout-level customization options that were previously available through <code>checkout.liquid<\/code>.\n<\/p>\n\n<p>\n    Cart attributes provide a reliable alternative because they automatically flow into <code>order.note_attributes<\/code> after checkout completion.\n<\/p>\n\n<p>\n    This approach:\n<\/p>\n\n<ul>\n    <li>Works on Shopify Basic plans<\/li>\n    <li>Requires no paid apps<\/li>\n    <li>Uses a stable and well-documented Shopify feature<\/li>\n    <li>Preserves attribution data throughout the purchase journey<\/li>\n<\/ul>\n\n<hr>\n\n<h3>The <code>client_id<\/code> Fallback Strategy<\/h3>\n\n<p>\n    In some situations, browser cookies may be blocked or a GA4 client ID may not be available. Since the GA4 Measurement Protocol requires a valid <code>client_id<\/code>, a fallback value can be generated dynamically.\n<\/p>\n\n<pre><code>const finalClientId = gaClientId ||\n  `${Math.floor(1000000000 + Math.random() * 9000000000)}.${customer.id || order.id}`;<\/code><\/pre>\n\n<p>\n    This ensures every Measurement Protocol request contains a valid client ID, allowing purchase events to be accepted and processed by GA4 even when cookie-based identifiers are unavailable.\n<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-45d0fda elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"45d0fda\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-17ffc52 elementor-widget elementor-widget-text-editor\" data-id=\"17ffc52\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Testing the Setup<\/h2>\n\n<h3>1. Verify Cart Attributes Are Saving<\/h3>\n\n<p>\n    Open your Shopify store in a browser, launch Developer Tools (<kbd>F12<\/kbd>), and run the following command in the Console:\n<\/p>\n\n<pre><code>fetch('\/cart.js')\n  .then(r => r.json())\n  .then(c => console.log('Cart attributes:', c.attributes))<\/code><\/pre>\n\n<p><strong>Expected Result:<\/strong><\/p>\n\n<pre><code>{\n  ga4_client_id: \"123456789.987654321\",\n  _fbp: \"fb.1.1234567890.123456789\"\n}<\/code><\/pre>\n\n<hr>\n\n<h3>2. Test UTM Capture<\/h3>\n\n<p>\n    Visit your store using a URL that contains UTM parameters:\n<\/p>\n\n<pre><code>https:\/\/your-store.com\/?utm_source=google&utm_medium=cpc&utm_campaign=test<\/code><\/pre>\n\n<p>\n    Run the cart attribute check again. You should now see values such as\n    <code>utm_source<\/code>, <code>utm_medium<\/code>, and <code>utm_campaign<\/code>\n    inside the cart attributes.\n<\/p>\n\n<hr>\n\n<h3>3. Verify Order Note Attributes<\/h3>\n\n<p>\n    Place a test order and navigate to:\n<\/p>\n\n<p>\n    <strong>Shopify Admin \u2192 Orders \u2192 [Your Test Order]<\/strong>\n<\/p>\n\n<p>\n    Scroll to the <strong>Additional Details<\/strong> section. All captured\n    attribution values should appear there as order note attributes.\n<\/p>\n\n<hr>\n\n<h3>4. Check Cloudflare Worker Logs<\/h3>\n\n<p>\n    Navigate to:\n<\/p>\n\n<p>\n    <strong>Cloudflare Dashboard \u2192 Workers \u2192 Your Worker \u2192 Logs \u2192 Real-time Logs<\/strong>\n<\/p>\n\n<p>\n    Send a test webhook from Shopify:\n<\/p>\n\n<p>\n    <strong>Settings \u2192 Notifications \u2192 Webhooks \u2192 Send Test<\/strong>\n<\/p>\n\n<p>\n    Watch the logs for a successful response similar to:\n<\/p>\n\n<pre><code>{\n  \"status\": \"success\",\n  \"meta\": { \"events_received\": 1 },\n  \"ga4_status\": 204\n}<\/code><\/pre>\n\n<hr>\n\n<h3>5. Verify in Meta Events Manager<\/h3>\n\n<p>\n    Open <strong>Events Manager \u2192 Test Events<\/strong> and place a real test order.\n<\/p>\n\n<p>\n    Confirm that a <strong>Purchase<\/strong> event appears and that the\n    <strong>Event Match Quality<\/strong> score is healthy.\n<\/p>\n\n<hr>\n\n<h2>Results You Can Expect<\/h2>\n\n<table>\n    <thead>\n        <tr>\n            <th>Metric<\/th>\n            <th>Before<\/th>\n            <th>After<\/th>\n        <\/tr>\n    <\/thead>\n    <tbody>\n        <tr>\n            <td>Meta Event Match Quality<\/td>\n            <td>Low<\/td>\n            <td>High<\/td>\n        <\/tr>\n        <tr>\n            <td>Purchase Event Accuracy<\/td>\n            <td>~60%<\/td>\n            <td>~90\u201395%<\/td>\n        <\/tr>\n        <tr>\n            <td>Draft Order False Events<\/td>\n            <td>Yes \u274c<\/td>\n            <td>No \u2705<\/td>\n        <\/tr>\n        <tr>\n            <td>POS Order False Events<\/td>\n            <td>Yes \u274c<\/td>\n            <td>No \u2705<\/td>\n        <\/tr>\n        <tr>\n            <td>GA4 UTM Attribution<\/td>\n            <td>Partial<\/td>\n            <td>Complete \u2705<\/td>\n        <\/tr>\n        <tr>\n            <td>iOS 14+ Resilience<\/td>\n            <td>Poor<\/td>\n            <td>Strong \u2705<\/td>\n        <\/tr>\n        <tr>\n            <td>Monthly Cost<\/td>\n            <td>Varies<\/td>\n            <td>$0 \u2705<\/td>\n        <\/tr>\n    <\/tbody>\n<\/table>\n\n<hr>\n\n<h2>Common Issues and Fixes<\/h2>\n\n<h3>Cart Attributes Are Empty (<code>{}<\/code>)<\/h3>\n\n<p>\n    GA4 or the Meta Pixel may not have loaded when the tracking script executed.\n    The script can only capture cookies that already exist, so verify that both\n    browser-side tracking implementations are installed and firing correctly.\n<\/p>\n\n<hr>\n\n<h3>Cloudflare Worker Returns a 500 Error<\/h3>\n\n<p>\n    Check the Real-time Logs in Cloudflare. A common cause is that Shopify test\n    webhooks sometimes use a slightly different payload structure than live orders.\n<\/p>\n\n<p>\n    The <code>body.order || body<\/code> fallback should handle most payload variations.\n<\/p>\n\n<hr>\n\n<h3>GA4 Returns 204 but No Events Appear<\/h3>\n\n<p>\n    The GA4 Measurement Protocol returns a <code>204<\/code> response even when event\n    validation fails.\n<\/p>\n\n<p>\n    For troubleshooting, temporarily replace:\n<\/p>\n\n<pre><code>mp\/collect<\/code><\/pre>\n\n<p>\n    with:\n<\/p>\n\n<pre><code>debug\/mp\/collect<\/code><\/pre>\n\n<p>\n    Review the validation response for any errors or warnings.\n<\/p>\n\n<hr>\n\n<h3>Meta Error: &#8220;Insufficient Customer Information&#8221;<\/h3>\n\n<p>\n    This usually occurs when a customer checks out as a guest and the customer\n    object contains little or no information.\n<\/p>\n\n<p>\n    Falling back to data from <code>shipping_address<\/code> for names and phone\n    numbers typically resolves the issue and improves Event Match Quality.\n<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-76e46dd elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"76e46dd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-25eceb0 elementor-widget elementor-widget-text-editor\" data-id=\"25eceb0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Conclusion<\/h2>\n\n<p>\n    Server-side tracking is no longer limited to enterprise brands with dedicated engineering teams.\n    By combining Shopify Webhooks, Cloudflare Workers&#8217; free tier, and a lightweight\n    <code>theme.liquid<\/code> implementation, store owners can build accurate and reliable\n    conversion tracking without additional software costs.\n<\/p>\n\n<p>\n    This setup provides:\n<\/p>\n\n<ul>\n    <li>\u2705 Accurate purchase tracking that remains resilient against ad blockers and iOS privacy restrictions<\/li>\n    <li>\u2705 Better Meta Ads optimization through improved Event Match Quality<\/li>\n    <li>\u2705 Complete GA4 attribution, including UTM campaign data<\/li>\n    <li>\u2705 Elimination of false conversion events from draft orders and POS sales<\/li>\n    <li>\u2705 GDPR-friendly data handling using SHA256 hashing<\/li>\n    <li>\u2705 Zero ongoing monthly software costs<\/li>\n<\/ul>\n\n<p>\n    Browser-side pixels and server-side tracking are most effective when used together.\n    Browser tracking supports audience creation and remarketing, while the server-side layer\n    ensures purchase conversions are captured accurately and consistently.\n<\/p>\n\n<div class=\"note-box\">\n    <p>\n        <strong>Implementation Notes:<\/strong>\n    <\/p>\n\n    <ul>\n        <li>Shopify Basic plan was used for testing.<\/li>\n        <li>Cloudflare Workers Free Tier (100,000 requests per day) was sufficient for all tracking operations.<\/li>\n        <li>No third-party Shopify apps were required.<\/li>\n        <li>No paid server-side tracking platforms or middleware services were used.<\/li>\n    <\/ul>\n<\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-36ef0b7 elementor-widget elementor-widget-html\" data-id=\"36ef0b7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n    \/* CTA Box *\/\r\n\r\n.cta-box {\r\n    margin: 50px 0;\r\n    padding: 40px;\r\n    border-radius: 16px;\r\n    background: #f8fafc;\r\n    border: 1px solid #e5e7eb;\r\n    text-align: center;\r\n}\r\n\r\n.cta-box h3 {\r\n    margin: 0 0 15px;\r\n    font-size: 32px;\r\n    line-height: 1.3;\r\n    font-weight: 700;\r\n    color: #111827;\r\n}\r\n\r\n.cta-box p {\r\n    max-width: 700px;\r\n    margin: 0 auto 25px;\r\n    font-size: 18px;\r\n    line-height: 1.7;\r\n    color: #4b5563;\r\n}\r\n\r\n.cta-box .btn {\r\n    display: inline-block;\r\n    padding: 14px 30px;\r\n    background: #2563eb;\r\n    color: #fff;\r\n    text-decoration: none;\r\n    font-weight: 600;\r\n    font-size: 16px;\r\n    border-radius: 8px;\r\n    transition: all 0.3s ease;\r\n}\r\n\r\n.cta-box .btn:hover {\r\n    background: #1d4ed8;\r\n    transform: translateY(-2px);\r\n}\r\n\r\n\/* Mobile *\/\r\n\r\n@media (max-width: 768px) {\r\n    .cta-box {\r\n        padding: 30px 20px;\r\n    }\r\n\r\n    .cta-box h3 {\r\n        font-size: 26px;\r\n    }\r\n\r\n    .cta-box p {\r\n        font-size: 16px;\r\n    }\r\n\r\n    .cta-box .btn {\r\n        width: 100%;\r\n        max-width: 300px;\r\n    }\r\n}\r\n<\/style>\r\n<div class=\"cta-box\">\r\n    <h3>Need Help Implementing Server-Side Tracking?<\/h3>\r\n\r\n    <p>\r\n        Whether you're running Shopify, Shopify Plus, or a custom eCommerce stack,\r\n        proper server-side tracking can significantly improve attribution accuracy,\r\n        campaign optimization, and reporting reliability.\r\n    <\/p>\r\n\r\n    <a href=\"\/contact-us\/\" class=\"btn\">\r\n        Request a Consultation\r\n    <\/a>\r\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re running a Shopify store and spending money on Meta Ads or Google Ads, you&#8217;re probably losing a significant [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":16287,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_angie_page":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"page_builder":"","footnotes":""},"categories":[24,22,65,63,56,96],"tags":[],"class_list":["post-16282","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artificial-intelligence","category-business","category-data-science","category-google-analytics","category-google-analytics-4ga4","category-shopify"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.8 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"admin\"\/>\n\t<meta name=\"google-site-verification\" content=\"fPDc_Oe-cOoXLK0xIJT8j8iApYX1HPe8R9G0XY_C4i0\" \/>\n\t<meta name=\"msvalidate.01\" content=\"CBBE445676E34C209DFF55CD8AA6A469\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.8\" \/>\n\n\t\t<meta name=\"ahrefs-site-verification\" content=\"ffa822e1e6e0947489b6a4bbcea59d9c5a71a0a9d2864c4a72c5e82a4e152a2e\">\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"- Your Partner in Tracking and Development\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png\" \/>\n\t\t<meta property=\"og:image:width\" content=\"1536\" \/>\n\t\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-06-15T06:49:19+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-06-15T07:00:54+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/palamsolutions\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:site\" content=\"@PalamSolutions\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.\" \/>\n\t\t<meta name=\"twitter:creator\" content=\"@PalamSolutions\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#blogposting\",\"name\":\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -\",\"headline\":\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)\",\"author\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png\",\"width\":1536,\"height\":1024},\"datePublished\":\"2026-06-15T02:49:19-04:00\",\"dateModified\":\"2026-06-15T03:00:54-04:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#webpage\"},\"articleSection\":\"Artificial Intelligence, Business, Data Science, Google Analytics, Google Analytics 4 - GA4, Shopify\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/category\\\/business\\\/#listItem\",\"name\":\"Business\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/category\\\/business\\\/#listItem\",\"position\":2,\"name\":\"Business\",\"item\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/category\\\/business\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#listItem\",\"name\":\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#listItem\",\"position\":3,\"name\":\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/category\\\/business\\\/#listItem\",\"name\":\"Business\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/#organization\",\"name\":\"Palam Solutions\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/\",\"telephone\":\"+919780900533\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/1-1-1.png\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#organizationLogo\"},\"image\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#organizationLogo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/palamsolutions\",\"https:\\\/\\\/twitter.com\\\/PalamSolutions\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/adf02bbe665457e856c98998177675c35cd32247d318ee050054626c152efbe8?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"admin\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#webpage\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/\",\"name\":\"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -\",\"description\":\"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\\u2014all with a free setup.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/author\\\/admin\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#mainImage\",\"width\":1536,\"height\":1024},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\\\/#mainImage\"},\"datePublished\":\"2026-06-15T02:49:19-04:00\",\"dateModified\":\"2026-06-15T03:00:54-04:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/\",\"name\":\"Palam Solutions\",\"description\":\"Your Partner in Tracking and Development\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.palamsolutions.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -","description":"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.","canonical_url":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"fPDc_Oe-cOoXLK0xIJT8j8iApYX1HPe8R9G0XY_C4i0","msvalidate.01":"CBBE445676E34C209DFF55CD8AA6A469","miscellaneous":"&lt;meta name=\"ahrefs-site-verification\" content=\"ffa822e1e6e0947489b6a4bbcea59d9c5a71a0a9d2864c4a72c5e82a4e152a2e\"&gt;"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#blogposting","name":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -","headline":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)","author":{"@id":"https:\/\/www.palamsolutions.com\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/www.palamsolutions.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png","width":1536,"height":1024},"datePublished":"2026-06-15T02:49:19-04:00","dateModified":"2026-06-15T03:00:54-04:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#webpage"},"isPartOf":{"@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#webpage"},"articleSection":"Artificial Intelligence, Business, Data Science, Google Analytics, Google Analytics 4 - GA4, Shopify"},{"@type":"BreadcrumbList","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.palamsolutions.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog\/category\/business\/#listItem","name":"Business"}},{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog\/category\/business\/#listItem","position":2,"name":"Business","item":"https:\/\/www.palamsolutions.com\/blog\/category\/business\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#listItem","name":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#listItem","position":3,"name":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)","previousItem":{"@type":"ListItem","@id":"https:\/\/www.palamsolutions.com\/blog\/category\/business\/#listItem","name":"Business"}}]},{"@type":"Organization","@id":"https:\/\/www.palamsolutions.com\/blog\/#organization","name":"Palam Solutions","url":"https:\/\/www.palamsolutions.com\/blog\/","telephone":"+919780900533","logo":{"@type":"ImageObject","url":"https:\/\/www.palamsolutions.com\/wp-content\/uploads\/2020\/03\/1-1-1.png","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#organizationLogo"},"image":{"@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#organizationLogo"},"sameAs":["https:\/\/www.facebook.com\/palamsolutions","https:\/\/twitter.com\/PalamSolutions"]},{"@type":"Person","@id":"https:\/\/www.palamsolutions.com\/blog\/author\/admin\/#author","url":"https:\/\/www.palamsolutions.com\/blog\/author\/admin\/","name":"admin","image":{"@type":"ImageObject","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/adf02bbe665457e856c98998177675c35cd32247d318ee050054626c152efbe8?s=96&d=mm&r=g","width":96,"height":96,"caption":"admin"}},{"@type":"WebPage","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#webpage","url":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/","name":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -","description":"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.palamsolutions.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#breadcrumblist"},"author":{"@id":"https:\/\/www.palamsolutions.com\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/www.palamsolutions.com\/blog\/author\/admin\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png","@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#mainImage","width":1536,"height":1024},"primaryImageOfPage":{"@id":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/#mainImage"},"datePublished":"2026-06-15T02:49:19-04:00","dateModified":"2026-06-15T03:00:54-04:00"},{"@type":"WebSite","@id":"https:\/\/www.palamsolutions.com\/blog\/#website","url":"https:\/\/www.palamsolutions.com\/blog\/","name":"Palam Solutions","description":"Your Partner in Tracking and Development","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.palamsolutions.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"- Your Partner in Tracking and Development","og:type":"article","og:title":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -","og:description":"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.","og:url":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/","og:image":"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png","og:image:secure_url":"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png","og:image:width":1536,"og:image:height":1024,"article:published_time":"2026-06-15T06:49:19+00:00","article:modified_time":"2026-06-15T07:00:54+00:00","article:publisher":"https:\/\/www.facebook.com\/palamsolutions","twitter:card":"summary_large_image","twitter:site":"@PalamSolutions","twitter:title":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup) -","twitter:description":"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.","twitter:creator":"@PalamSolutions","twitter:image":"https:\/\/www.palamsolutions.com\/blog\/wp-content\/uploads\/2026\/06\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup.png"},"aioseo_meta_data":{"post_id":"16282","title":null,"description":"Learn how to set up Shopify server-side tracking using Meta Conversions API (CAPI), GA4 Measurement Protocol, and Cloudflare Workers. Improve attribution accuracy, track purchases reliably, capture UTM data, and eliminate false conversions\u2014all with a free setup.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":[],"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-06-15 05:44:57","updated":"2026-06-15 17:46:30","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.palamsolutions.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.palamsolutions.com\/blog\/category\/business\/\" title=\"Business\">Business<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tShopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.palamsolutions.com\/blog"},{"label":"Business","link":"https:\/\/www.palamsolutions.com\/blog\/category\/business\/"},{"label":"Shopify Server-Side Tracking: Meta CAPI + GA4 with Cloudflare Workers (Free Setup)","link":"https:\/\/www.palamsolutions.com\/blog\/shopify-server-side-tracking-meta-capi-ga4-with-cloudflare-workers-free-setup\/"}],"_links":{"self":[{"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/16282","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=16282"}],"version-history":[{"count":5,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/16282\/revisions"}],"predecessor-version":[{"id":16290,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/16282\/revisions\/16290"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/media\/16287"}],"wp:attachment":[{"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=16282"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=16282"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.palamsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=16282"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}