Compare commits

...

2 Commits

Author SHA1 Message Date
cbe900a8e4 Umami tracking
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/build unknown status
ci/woodpecker/push/deploy unknown status
2026-02-17 01:28:18 -03:00
1033101c6f Umami analytics 2026-02-17 01:25:58 -03:00
2 changed files with 31 additions and 0 deletions

View File

@@ -63,6 +63,11 @@
src="https://www.googletagmanager.com/gtag/js?id={gaId}"
></script>
<script defer src="/assets/js/ga-init.js" data-ga-id={gaId}></script>
<script
defer
src="https://analytics.mifi.holdings/script.js"
data-website-id="753dc25e-84e9-48fa-b56c-a85ad6da8f87"
></script>
{@html `<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>`}
</svelte:head>

View File

@@ -1,5 +1,13 @@
const root = document.documentElement;
const saved = window?.localStorage?.getItem('theme');
// Umami: safe track (no-op if script blocked or not loaded)
function umamiTrack(name, data) {
if (typeof window.umami !== 'undefined' && typeof window.umami.track === 'function') {
if (data != null) window.umami.track(name, data);
else window.umami.track(name);
}
}
const sysDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (saved) {
@@ -27,6 +35,23 @@ if (themeToggle) {
});
}
// Umami: scroll depth (25%, 50%, 75%, 100%) once per milestone
const scrollMilestones = new Set();
function onScroll() {
const doc = document.documentElement;
const scrollTop = doc.scrollTop || document.body.scrollTop;
const scrollHeight = (doc.scrollHeight || document.body.scrollHeight) - window.innerHeight;
if (scrollHeight <= 0) return;
const pct = Math.round((scrollTop / scrollHeight) * 100);
for (const m of [25, 50, 75, 100]) {
if (pct >= m && !scrollMilestones.has(m)) {
scrollMilestones.add(m);
umamiTrack('scroll-depth', { depth: String(m) });
}
}
}
window.addEventListener('scroll', onScroll, { passive: true });
// Lightbox (structure from Lightbox.svelte; we fill content and handle open/close)
const dialog = document.querySelector('dialog.lightbox');
const lbContent = dialog?.querySelector('.lb-content');
@@ -71,6 +96,7 @@ function openLightbox(name, type, caption) {
lbContent.replaceChildren(picture);
}
lbCaption.textContent = caption || '';
umamiTrack('gallery-view', { name, type });
dialog.removeAttribute('inert');
dialog.setAttribute('aria-hidden', 'false');
dialog.showModal();