From d343e4b7f85bae58d2224064721dfaaba45f957c Mon Sep 17 00:00:00 2001 From: "Ignacio Ceballos (Yayo)" Date: Mon, 13 Jan 2025 17:31:51 +0100 Subject: [PATCH] add basic analytics --- public/analytics.js | 169 ++++++++++++++++++++++++++++++++++++++++++++ public/index.html | 5 ++ 2 files changed, 174 insertions(+) create mode 100644 public/analytics.js diff --git a/public/analytics.js b/public/analytics.js new file mode 100644 index 0000000000..eb587e93cd --- /dev/null +++ b/public/analytics.js @@ -0,0 +1,169 @@ +!(function () { + "use strict"; + ((t) => { + const { + screen: { width: e, height: a }, + navigator: { language: r }, + location: n, + document: i, + history: s, + } = t, + { hostname: c, href: o, origin: u } = n, + { currentScript: l, referrer: d } = i, + h = o.startsWith("data:") ? void 0 : t.localStorage; + if (!l) return; + const m = "data-", + f = "true", + p = l.getAttribute.bind(l), + g = p(m + "website-id"), + y = p(m + "host-url"), + b = p(m + "tag"), + v = "false" !== p(m + "auto-track"), + w = p(m + "exclude-search") === f, + S = p(m + "exclude-hash") === f, + N = p(m + "domains") || "", + T = N.split(",").map((t) => t.trim()), + A = `${( + y || + "https://api-gateway.umami.dev" || + l.src.split("/").slice(0, -1).join("/") + ).replace(/\/$/, "")}/api/send`, + j = `${e}x${a}`, + x = /data-umami-event-([\w-_]+)/, + O = m + "umami-event", + k = 300, + E = (t) => { + try { + const { pathname: e, search: a, hash: r } = new URL(t, n.href); + return e + (w ? "" : a) + (S ? "" : r); + } catch (e) { + return t; + } + }, + L = () => ({ + website: g, + hostname: c, + screen: j, + language: r, + title: J, + url: C, + referrer: I, + tag: b || void 0, + }), + $ = (t, e, a) => { + a && ((I = C), (C = E(a.toString())), C !== I && setTimeout(D, k)); + }, + K = () => + M || !g || (h && h.getItem("umami.disabled")) || (N && !T.includes(c)), + U = async (t, e = "event") => { + if (K()) return; + const a = { "Content-Type": "application/json" }; + void 0 !== _ && (a["x-umami-cache"] = _); + try { + const r = await fetch(A, { + method: "POST", + body: JSON.stringify({ type: e, payload: t }), + headers: a, + }), + n = await r.json(); + n && ((M = !!n.disabled), (_ = n.cache)); + } catch (t) {} + }, + B = () => { + q || + (D(), + (() => { + const t = (t, e, a) => { + const r = t[e]; + return (...e) => (a.apply(null, e), r.apply(t, e)); + }; + (s.pushState = t(s, "pushState", $)), + (s.replaceState = t(s, "replaceState", $)); + })(), + (() => { + const t = new MutationObserver(([t]) => { + J = t && t.target ? t.target.text : void 0; + }), + e = i.querySelector("head > title"); + e && + t.observe(e, { subtree: !0, characterData: !0, childList: !0 }); + })(), + i.addEventListener( + "click", + async (t) => { + const e = (t) => ["BUTTON", "A"].includes(t), + a = async (t) => { + const e = t.getAttribute.bind(t), + a = e(O); + if (a) { + const r = {}; + return ( + t.getAttributeNames().forEach((t) => { + const a = t.match(x); + a && (r[a[1]] = e(t)); + }), + D(a, r) + ); + } + }, + r = t.target, + i = e(r.tagName) + ? r + : ((t, a) => { + let r = t; + for (let t = 0; t < a; t++) { + if (e(r.tagName)) return r; + if (((r = r.parentElement), !r)) return null; + } + })(r, 10); + if (!i) return a(r); + { + const { href: e, target: r } = i, + s = i.getAttribute(O); + if (s) + if ("A" === i.tagName) { + const c = + "_blank" === r || + t.ctrlKey || + t.shiftKey || + t.metaKey || + (t.button && 1 === t.button); + if (s && e) + return ( + c || t.preventDefault(), + a(i).then(() => { + c || (n.href = e); + }) + ); + } else if ("BUTTON" === i.tagName) return a(i); + } + }, + !0 + ), + (q = !0)); + }, + D = (t, e) => + U( + "string" == typeof t + ? { ...L(), name: t, data: "object" == typeof e ? e : void 0 } + : "object" == typeof t + ? t + : "function" == typeof t + ? t(L()) + : L() + ), + W = (t) => U({ ...L(), data: t }, "identify"); + t.umami || (t.umami = { track: D, identify: W }); + let _, + q, + C = E(o), + I = d.startsWith(u) ? "" : d, + J = i.title, + M = !1; + v && + !K() && + ("complete" === i.readyState + ? B() + : i.addEventListener("readystatechange", B, !0)); + })(window); +})(); diff --git a/public/index.html b/public/index.html index 8ffe93dd82..fa6012499a 100644 --- a/public/index.html +++ b/public/index.html @@ -57,6 +57,11 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> +