awesome-prometheus-alerts/site/src/scripts/sponsor.ts
Samuel Berthe 5a5976c9a3
feat: track sponsor clicks with blocking event before navigation
- Add recordCopy() for copy events (bumps session/lifetime counters)
- Add recordAndWait() for blocking events (1500ms timeout, errors swallowed)
- Extract shared sponsor click handler into site/src/scripts/sponsor.ts
- Plain left-click blocks navigation until HTTP response; modifier/middle
  clicks track fire-and-forget and let the browser navigate natively
- Distinguish header vs footer placement via data-sponsor-slot attribute
2026-04-15 16:28:25 +02:00

33 lines
1.2 KiB
TypeScript

import { record, recordAndWait } from './pipe';
export function initSponsorClickTracking(): void {
document.querySelectorAll<HTMLAnchorElement>('a[data-sponsor-name]').forEach((a) => {
a.addEventListener('click', async (e) => {
const me = e as MouseEvent;
const href = a.href;
const sponsorName = a.dataset.sponsorName!;
const sponsorSlot = a.dataset.sponsorSlot!;
const eventData = { sponsor_name: sponsorName, sponsor_url: href, sponsor_slot: sponsorSlot };
// Modifier / non-primary clicks: track fire-and-forget, let browser handle navigation
if (me.button !== 0 || me.metaKey || me.ctrlKey || me.shiftKey) {
record('sponsor_click', eventData);
return;
}
// Plain left-click: block navigation until event is recorded
e.preventDefault();
// Open blank tab now (inside user gesture) to avoid popup-blocker after await
const w = a.target === '_blank' ? window.open('', '_blank') : null;
try {
await recordAndWait('sponsor_click', eventData);
} finally {
if (w) {
w.location.href = href;
} else {
window.open(href, '_blank') ?? (window.location.href = href);
}
}
});
});
}