add umami analytics loader
This commit is contained in:
@@ -55,5 +55,8 @@
|
|||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"svelte"
|
"svelte"
|
||||||
]
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@types/umami": "^2.10.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -7,6 +7,10 @@ settings:
|
|||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@types/umami':
|
||||||
|
specifier: ^2.10.1
|
||||||
|
version: 2.10.1
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@eslint/compat':
|
'@eslint/compat':
|
||||||
specifier: ^1.4.0
|
specifier: ^1.4.0
|
||||||
@@ -480,6 +484,9 @@ packages:
|
|||||||
'@types/node@24.10.4':
|
'@types/node@24.10.4':
|
||||||
resolution: {integrity: sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==}
|
resolution: {integrity: sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==}
|
||||||
|
|
||||||
|
'@types/umami@2.10.1':
|
||||||
|
resolution: {integrity: sha512-CvOEMq+BFOUXj8yciq4hPsdOt0o9KBg5jQXnF1FrdOMKZMxJiwryyZNLa9Ud2NVO6nXSwU22YMKR3E+Xhbo+DA==}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.50.0':
|
'@typescript-eslint/eslint-plugin@8.50.0':
|
||||||
resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==}
|
resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -1451,6 +1458,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 7.16.0
|
undici-types: 7.16.0
|
||||||
|
|
||||||
|
'@types/umami@2.10.1': {}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)':
|
'@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.2
|
'@eslint-community/regexpp': 4.12.2
|
||||||
|
|||||||
78
src/lib/Umami.svelte
Normal file
78
src/lib/Umami.svelte
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { dev } from '$app/environment';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import type { TrackingManager } from './tracking.svelte.ts';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* The URL of the Umami instance. For example: https://umami.example.com.
|
||||||
|
* Do not include a trailing slash, the script path will be appended
|
||||||
|
* automatically (default: /script.js).
|
||||||
|
*/
|
||||||
|
umamiURL: string;
|
||||||
|
/** Website ID to associate tracking data as configured in Umami */
|
||||||
|
websiteID: string;
|
||||||
|
/**
|
||||||
|
* Tracking manager to handle user consent for tracking. If omitted,
|
||||||
|
* tracking will always be enabled.
|
||||||
|
*/
|
||||||
|
trackingManager?: TrackingManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { umamiURL, websiteID, trackingManager }: Props = $props();
|
||||||
|
|
||||||
|
const consentGranted = $derived(trackingManager ? trackingManager.consent === true : true);
|
||||||
|
|
||||||
|
// Development overrides to prevent dirty analytics
|
||||||
|
const devConsoleTag = $derived(`[dev][consent: ${consentGranted ? 'granted' : 'revoked'}]`);
|
||||||
|
const devOverride = {
|
||||||
|
track: (...args: unknown[]): Promise<string> | undefined => {
|
||||||
|
console.log(`${devConsoleTag}: Track called with:`, ...args);
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
identify: (...args: unknown[]): Promise<void> => {
|
||||||
|
console.log(`${devConsoleTag}: Identify called with:`, ...args);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// No-consent quiet override
|
||||||
|
const noConsentOverride = {
|
||||||
|
track: (..._args: unknown[]): Promise<string> | undefined => {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
identify: (..._args: unknown[]): Promise<void> => {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// If a tracking manager is provided, use it to manage consent state
|
||||||
|
$effect(() => {
|
||||||
|
if (trackingManager) {
|
||||||
|
trackingManager.createService({
|
||||||
|
onConsent: () => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onRevoke: () => {
|
||||||
|
window.umami = noConsentOverride;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dev) console.log('[dev]: Umami tracking disabled');
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (dev) {
|
||||||
|
// In development mode, override the umami global object
|
||||||
|
window.umami = devOverride;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
{#if !dev && consentGranted}
|
||||||
|
<script defer src="{umamiURL}/script.js" data-website-id={websiteID}></script>
|
||||||
|
{/if}
|
||||||
|
</svelte:head>
|
||||||
Reference in New Issue
Block a user