build / build (pull_request) Successful in 1m10s
trackEvent queues events until the deferred Umami script exists (they were dropped when fired in onMounted) and drops them silently after 10 s. The result page sends purchase-completed with revenue/currency once per order (localStorage guard, set only after sending). The plugin honours Do Not Track and loads recorder.js only on /details/* for Umami heatmaps. bun test utils/trackEvent.test.ts: 4 pass. Netcup #115.
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
export default defineNuxtPlugin(() => {
|
|
const config = useRuntimeConfig();
|
|
const scriptUrl = config.public.umamiScriptUrl as string;
|
|
const websiteId = config.public.umamiWebsiteId as string;
|
|
if (!scriptUrl || !websiteId) return;
|
|
|
|
useHead({
|
|
script: [
|
|
{
|
|
src: scriptUrl,
|
|
defer: true,
|
|
"data-website-id": websiteId,
|
|
"data-do-not-track": "true"
|
|
}
|
|
]
|
|
});
|
|
|
|
// Heatmap recorder only on product pages (no personal data there). It needs
|
|
// heatmapEnabled on the Umami website, set via umami/analytics/reports.json.
|
|
const recorderUrl = scriptUrl.replace(/script\.js(\?.*)?$/, "recorder.js");
|
|
let recorderLoaded = false;
|
|
const loadRecorder = (path: string) => {
|
|
if (recorderLoaded || !path.startsWith("/details/")) return;
|
|
if (navigator.doNotTrack === "1") return;
|
|
recorderLoaded = true;
|
|
const el = document.createElement("script");
|
|
el.src = recorderUrl;
|
|
el.defer = true;
|
|
el.dataset.websiteId = websiteId;
|
|
document.head.appendChild(el);
|
|
};
|
|
const router = useRouter();
|
|
loadRecorder(router.currentRoute.value.path);
|
|
router.afterEach((to) => loadRecorder(to.path));
|
|
});
|