-
-
Save mindplay-dk/8154b3d6583eec36bd82e11c741ca585 to your computer and use it in GitHub Desktop.
Simplified GA4 tracking script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simplified GA4 tracking script | |
// based on https://gist.github.com/idarek/9ade69ac2a2ef00d98ab950426af5791 | |
(() => { | |
const tid = "G-XXXXXXXXXX"; // set your GA4 Measurement ID here | |
function serialize(input) { | |
const output = {}; | |
for (const key in input) { | |
if (input[key] != null) { | |
output[key] = input[key]; | |
} | |
} | |
return (new URLSearchParams(output)).toString(); | |
} | |
// TODO add timestamp to storage state and clear the session ID (sid) | |
// if the last track() call was more than 30 minutes ago | |
// (test this with an initial 30 second timeout) | |
// add expiration timeout constants for both client and session IDs. | |
// TODO use an object to store the values instead of localStorage, | |
// write the whole object to localStorage at the end of track() | |
// and store the whole state in a single JSON storage item. | |
const get = (name, init) => localStorage[name] || (init && set(name, init())); | |
const set = (name, value) => localStorage[name] = value; | |
const createID = () => Math.floor(Math.random() * 2147483647) + 1; | |
const getTime = () => Math.floor(Date.now() / 1000); | |
const _p = createID(); // Page ID | |
let _s = 1; // Sequence number | |
const CLIENT_ID = "ga_cid"; | |
const SESSION_ID = "ga_sid"; | |
const SESSION_COUNT = "ga_sct"; | |
const seg = get(SESSION_ID) ? 1 : 0; // Session engaged | |
function track(en, params = {}) { | |
// First Visit | |
const _fv = get(CLIENT_ID) ? null : 1; | |
// Generate or retrieve client ID | |
const cid = get(CLIENT_ID, () => createID() + "." + getTime()); | |
// Session start | |
const _ss = get(SESSION_ID) ? null : 1; | |
// Session ID | |
const sid = get(SESSION_ID, getTime); | |
// Session count | |
const sct = _ss // session started? | |
? set(SESSION_COUNT, parseInt(get(SESSION_COUNT, () => "0")) + 1) // increment session count | |
: get(SESSION_COUNT); // report current session count | |
const data = serialize({ | |
v: 2, // Protocol Version | |
tid, // Measurement ID | |
_p, // Page ID | |
cid, // Client ID | |
ul: (navigator.language || "").toLowerCase(), // User Language | |
sr: (screen.width + "x" + screen.height), // Screen Resolution | |
_s: _s++, // Sequence number | |
sid, // Session ID | |
sct, // Session count | |
seg, // Session engaged | |
dl: document.location.origin + document.location.pathname + document.location.search, // Document Location (without fragment) | |
dr: document.referrer, | |
dt: document.title, | |
en, // Event Name | |
_fv, // First Visit | |
_ss, // Session Start | |
_dbg: 1, // Debug Mode | |
// custom event params: | |
...Object.fromEntries( | |
Object.entries(params).map(([key, value]) => [`ep.${key}`, value]) | |
) | |
}); | |
const url = "https://www.google-analytics.com/g/collect"; | |
// Send the hit using the most appropriate available method | |
if (navigator.sendBeacon) { | |
navigator.sendBeacon(url + "?" + data); | |
} else { | |
fetch(url + "?" + data, { | |
method: "POST", | |
keepalive: true | |
}); | |
} | |
} | |
// Send the page view | |
track("page_view"); | |
window.track = track; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment