/** * meta_tracking.js * A standalone module to capture and persist Meta attribution signals (fbclid, _fbp) in cookies. * * Logic adapted for legacy environment (no React hooks). * - Checks URL for `fbclid` and sets `_fbc` cookie. * - Checks for `_fbp` cookie; if missing, generates and sets it. */ (function(window, document) { 'use strict'; var MetaTracking = { init: function() { var location = window.location; this.handleFbc(location.search); this.handleFbp(); }, // 1. Parsing and storing _fbc (Click ID) handleFbc: function(searchParams) { var fbclid = this.getQueryParam('fbclid', searchParams); if (fbclid) { var version = 'fb'; var subdomainIndex = 1; // 1 = example.com var creationTime = new Date().getTime(); // Unix timestamp in ms // Format: fb.1.timestamp.id var fbcValue = version + '.' + subdomainIndex + '.' + creationTime + '.' + fbclid; this.setCookie('_fbc', fbcValue, 90); } }, // 2. Handling _fbp (Browser ID) handleFbp: function() { if (!this.getCookie('_fbp')) { var version = 'fb'; var subdomainIndex = 1; var creationTime = new Date().getTime(); var randomInt = Math.floor(Math.random() * 10000000000); // 10-digit random number // Format: fb.1.timestamp.randomDigits var fbpValue = version + '.' + subdomainIndex + '.' + creationTime + '.' + randomInt; this.setCookie('_fbp', fbpValue, 90); } }, // Helper: Get query param by name getQueryParam: function(name, search) { name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'); var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'); var results = regex.exec(search); return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')); }, // Helper: Set cookie setCookie: function(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } // Ensure path is root and domain is included if needed (defaults to current host) document.cookie = name + "=" + (value || "") + expires + "; path=/"; }, // Helper: Get cookie getCookie: function(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } }; // Initialize on ready if (document.readyState === 'complete' || document.readyState === 'interactive') { MetaTracking.init(); } else { // IE9+ support for DOMContentLoaded document.addEventListener('DOMContentLoaded', function() { MetaTracking.init(); }); } })(window, document);