Skip to content

Instantly share code, notes, and snippets.

View thyngster's full-sized avatar

David Vallejo thyngster

View GitHub Profile
@thyngster
thyngster / gtm_load_performance.js
Created February 6, 2026 08:38
GTM Load Performance
(function() {
const targetScript = "gtm.js";
function fmt(ms) { return ms.toFixed(2) + "ms"; }
// Poll performance entries until we find GTM.js
const checkInterval = 50; // ms
const maxAttempts = 100; // ~5 seconds max
let attempts = 0;
@thyngster
thyngster / dataLayerMonitor.js
Created February 6, 2026 02:31
dataLayer Integrity Monitor
(function protectDataLayer() {
window._internalDataLayer = window.dataLayer || [];
// Wrap the array in a Proxy to detect internal changes
const dataLayerProxy = new Proxy(window._internalDataLayer, {
set(target, prop, value, receiver) {
console.log(`[dataLayer] Change detected: "${prop}" set to`, value);
return Reflect.set(target, prop, value, receiver);
},
get(target, prop, receiver) {
@thyngster
thyngster / ga4_cookie_monitor.js
Created February 6, 2026 01:30
GA4 Cookie Changes Monitor
@thyngster
thyngster / cookiestore_report_list.js
Created February 6, 2026 00:59
Function to Export a JSON will all cookies
async function getCookieReport() {
// Helper: human-friendly duration
function formatDuration(ms) {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
if (months >= 1) return months === 1 ? "1 month" : `${months} months`;
@thyngster
thyngster / ga4CookieParser.js
Created April 12, 2025 06:01
GA4 COOKIES PARSER
/**
* Parses GA4 cookies using a measurement ID without polluting the global namespace
* @param {string} measurementId - GA4 measurement ID (e.g., 'G-XXXXXXXX')
* @returns {Object|null} Parsed GA4 cookie data or null if cookies not found
*/
function parseGA4Cookies(measurementId) {
function getCookieValue(name) {
const match = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
return match ? match.pop() : null;
}
@thyngster
thyngster / move.js
Created April 12, 2025 03:29
Movement Detector
class MovementDetector {
constructor(options = {}) {
// Configuration with defaults
this.threshold = options.threshold || 5;
this.debug = options.debug || false;
this.onMovementChange = options.onMovementChange || null;
// State tracking
this.lastRotation = { x: 0, y: 0, z: 0 };
this.isMoving = false;
@thyngster
thyngster / wpo.js
Created April 12, 2025 03:06
WPO Metrics Tracker
(function(){
var wpo = {
redirects: window.performance.navigation.redirectCount,
resources: {
iframe: 0,
img: 0,
css: 0,
script: 0,
beacon: 0,
xmlhttprequest: 0,
@thyngster
thyngster / cid_monitor.js
Last active April 12, 2025 01:15
Monitor GA Client ID
(function() {
let ga_cid = document.cookie
.split('; ')
.find(row => row.startsWith('_ga='))
?.split('=')[1];
// Listen for changes in the cookie store
cookieStore.addEventListener('change', (e) => {
e.changed.forEach(c => {
if (c.name.startsWith('_ga')) {
@thyngster
thyngster / getLoadedGA4Containers.js
Last active May 2, 2024 12:39
Small function to check if any GA4 Container has been currently been loaded.
// DV - 2022 - ES5
// Check if GA4 has been loaded
var getLoadedGA4Containers = function() {
return Object.keys(
window.google_tag_data &&
window.google_tag_data.tidr &&
window.google_tag_data.tidr.container || {}
).filter(function(e){ return e.startsWith('G-') })
}
@thyngster
thyngster / privacy_sandbox_apis_check.js
Created February 27, 2024 21:18
Privacy Sandbox Relevance & Measurement APIs Check
// ----------------------------------------------------------------------
// Privacy Sandbox Relevance & Measurement APIs Check
// ----------------------------------------------------------------------
const privacySandboxApisAvailability = {
topics: 'browsingTopics'in document ? true : false,
attributionReporting: document.featurePolicy.allowsFeature('attribution-reporting') ? true : false,
protectedAudience: 'runAdAuction'in navigator ? true : false,
fencedFrames: 'HTMLFencedFrameElement'in window ? true : false,
sharedStorage: 'sharedStorage'in window ? true : false,