feat: add Meta CAPI + Google Enhanced Conversions server-side tracking
- Add /api/conversions endpoint (Meta CAPI + GA4 Measurement Protocol) - SHA-256 PII hashing, event_id deduplication, fbp/fbc cookies - Client-side sendConversion() utility in PageShell.astro - Lead event tracking on form submit in home.js - GA4 allow_enhanced_conversions config
This commit is contained in:
@@ -78,16 +78,18 @@ const organizationJsonLd = JSON.stringify({
|
||||
<!-- ConsentOS (cookie consent — load first) -->
|
||||
<script src="https://consent.moreminimore.com/consent-loader.js" data-site-id="2f6d0ab5-f7d6-4d06-b299-5069c21f6238" data-api-base="https://consent.moreminimore.com"></script>
|
||||
|
||||
<!-- Google Analytics 4 -->
|
||||
<!-- Google Analytics 4 + Enhanced Conversions -->
|
||||
<script is:inline async src="https://www.googletagmanager.com/gtag/js?id=G-74BHREDLC3"></script>
|
||||
<script is:inline>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-74BHREDLC3');
|
||||
gtag('config', 'G-74BHREDLC3', {
|
||||
allow_enhanced_conversions: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Meta Pixel -->
|
||||
<!-- Meta Pixel + event_id support -->
|
||||
<script is:inline>
|
||||
!function(f,b,e,v,n,t,s)
|
||||
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
||||
@@ -98,7 +100,57 @@ const organizationJsonLd = JSON.stringify({
|
||||
s.parentNode.insertBefore(t,s)}(window, document,'script',
|
||||
'https://connect.facebook.net/en_US/fbevents.js');
|
||||
fbq('init', '418349260078648');
|
||||
fbq('track', 'PageView');
|
||||
|
||||
// Generate event_id for PageView deduplication
|
||||
var pvEventId = 'pv_' + Date.now() + '_' + Math.random().toString(36).substr(2,9);
|
||||
fbq('track', 'PageView', {}, {eventID: pvEventId});
|
||||
</script>
|
||||
|
||||
<!-- Conversion Tracking Utilities -->
|
||||
<script is:inline>
|
||||
window.generateEventId = function(prefix) {
|
||||
return (prefix || 'evt') + '_' + Date.now() + '_' +
|
||||
Math.random().toString(36).substr(2,9) +
|
||||
Math.random().toString(36).substr(2,9);
|
||||
};
|
||||
|
||||
window.getMetaCookies = function() {
|
||||
var c = document.cookie.split(';').reduce(function(a,x) {
|
||||
var p = x.trim().split('=');
|
||||
a[p[0]] = p[1]; return a;
|
||||
}, {});
|
||||
return { fbp: c._fbp || null, fbc: c._fbc || null };
|
||||
};
|
||||
|
||||
window.sendConversion = function(eventName, eventData, userInfo) {
|
||||
var eventId = window.generateEventId(eventName.toLowerCase());
|
||||
var mc = window.getMetaCookies();
|
||||
|
||||
// Client-side fire
|
||||
if (window.fbq) fbq('track', eventName, eventData || {}, {eventID: eventId});
|
||||
if (window.gtag) gtag('event', eventName, eventData || {});
|
||||
|
||||
// Server-side: Meta CAPI + Google EC
|
||||
fetch('/api/conversions', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
event_name: eventName,
|
||||
event_id: eventId,
|
||||
event_time: Math.floor(Date.now() / 1000),
|
||||
event_source_url: window.location.href,
|
||||
user_data: {
|
||||
em: userInfo?.email || null,
|
||||
ph: userInfo?.phone || null,
|
||||
fn: userInfo?.firstName || null,
|
||||
ln: userInfo?.lastName || null,
|
||||
fbp: mc.fbp,
|
||||
fbc: mc.fbc
|
||||
},
|
||||
custom_data: eventData || {}
|
||||
})
|
||||
}).catch(function(e) { console.error('[CAPI]', e); });
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Umami Analytics -->
|
||||
|
||||
Reference in New Issue
Block a user