Updated Script which also handles pending events
const BUILDER_STORAGE_KEY = 'builderPendingEvents';
const API_KEY = 'c0a2ee2c3a9544daas'; // Updated API key
const MAX_RETRIES = 3;
const RETRY_DELAY = 1000;
// Helper function to safely get storage data
const getPendingEvents = () => {
try {
const stored = localStorage.getItem(BUILDER_STORAGE_KEY);
return stored ? JSON.parse(stored) : [];
} catch (e) {
console.error('Error reading pending events:', e);
return [];
}
};
// Helper function to safely store data
const storePendingEvent = (eventData) => {
try {
const events = getPendingEvents();
events.push(eventData);
localStorage.setItem(BUILDER_STORAGE_KEY, JSON.stringify(events));
} catch (e) {
console.error('Error storing pending event:', e);
}
};
// Helper function to remove stored events
const removePendingEvents = () => {
try {
localStorage.removeItem(BUILDER_STORAGE_KEY);
} catch (e) {
console.error('Error removing pending events:', e);
}
};
// Function to send tracking data to Builder.io
const sendToBuilder = async (eventData, retryCount = 0) => {
try {
console.log("Sending to Builder...", eventData);
const response = await fetch(
`https://cdn.builder.io/api/v1/track?apiKey=${API_KEY}`,
{
method: 'POST',
body: JSON.stringify({ events: [eventData] }),
headers: {
'content-type': 'application/json',
},
mode: 'cors',
keepalive: true,
}
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
console.log("Builder response:", response);
return true;
} catch (error) {
console.error('Tracking error:', error);
if (retryCount < MAX_RETRIES) {
await new Promise((resolve) =>
setTimeout(resolve, RETRY_DELAY * (retryCount + 1))
);
return sendToBuilder(eventData, retryCount + 1);
}
storePendingEvent(eventData);
return false;
}
};
// Main tracking function
const trackConversion = ({ amountInfo, meta = {} }) => {
console.log("Track Conversion Started...");
const sessionId = document.cookie
.split('; ')
.find((row) => row.startsWith('builderSessionId='))
?.split('=')[1] || null;
const variationId = document.cookie
.split('; ')
.find((row) => row.startsWith('builder.tests='))
?.split('=')[1] || null;
const visitorId = localStorage.getItem('builderVisitorId') || null;
console.log("Session ID:", sessionId);
console.log("Variation ID:", variationId);
console.log("Visitor ID:", visitorId);
console.log("Amount:", amountInfo.amount);
const eventData = {
type: 'conversion',
data: {
amount: amountInfo.amount,
metadata: {
sdkVersion: '3.2.10',
url: location.href,
currency: amountInfo.currencyCode,
timestamp: new Date().toISOString(),
...meta,
},
ownerId: API_KEY,
userAttributes: {
sessionId,
visitorId,
variationId,
},
sessionId,
visitorId,
},
};
console.log("Event data being sent:", eventData);
return sendToBuilder(eventData);
};
// Setup main event listener
analytics.subscribe('checkout_completed', (event) => {
console.log("Checkout Completed Event Received:", event);
if (!event.data || !event.data.checkout) {
console.error('Invalid checkout data received');
return;
}
const checkout = event.data.checkout;
console.log("Processing checkout:", checkout);
trackConversion({
amountInfo: checkout.totalPrice,
meta: {
additionalData: 'Conversion Recorded',
eventId: event.id,
clientId: event.clientId,
},
});
});
// Try to send pending events on page load
window.addEventListener('load', async () => {
const pendingEvents = getPendingEvents();
if (pendingEvents.length > 0) {
console.log("Processing pending events:", pendingEvents);
const results = await Promise.all(
pendingEvents.map((event) => sendToBuilder(event))
);
if (results.every(Boolean)) {
removePendingEvents();
}
}
});
// Backup tracking before page unload
window.addEventListener('beforeunload', () => {
const pendingEvents = getPendingEvents();
if (pendingEvents.length > 0) {
try {
navigator.sendBeacon(
`https://cdn.builder.io/api/v1/track?apiKey=${API_KEY}`,
JSON.stringify({ events: pendingEvents })
);
removePendingEvents();
} catch (e) {
console.error('Error sending beacon:', e);
}
}
});