From c96d97e1545421d20ad583a5fccb853e4064149e Mon Sep 17 00:00:00 2001 From: Santhosh Janardhanan Date: Mon, 13 Apr 2026 01:21:20 -0400 Subject: [PATCH] feat: add Umami analytics with tagged events Add Umami web analytics tracking script to the layout head, and instrument all interactive elements with event tracking: Declarative (data-umami-event attributes): - Category selector: select_category - Style selector: select_style - Intensity slider: adjust_intensity - Prompt toggle: toggle_prompt (with open/close action) Programmatic (umami.track with metadata): - convert_click: { style, intensity } - convert_success: { style, intensity, model } - convert_error: { style, intensity, error } - copy_result: { style } --- src/app.d.ts | 5 +++++ src/routes/+layout.svelte | 1 + src/routes/+page.svelte | 22 ++++++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/app.d.ts b/src/app.d.ts index da08e6d..237d1fd 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -8,6 +8,11 @@ declare global { // interface PageState {} // interface Platform {} } + + // Umami analytics tracker (injected by script tag) + const umami: { + track(event: string, data?: Record): void; + }; } export {}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 828a2f5..0807623 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -6,6 +6,7 @@ + {@render children()} \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 836befc..b9ab318 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -78,6 +78,10 @@ async function handleConvert() { if (!canConvert) return; + if (typeof umami !== 'undefined') { + umami.track('convert_click', { style: selectedStyleId, intensity }); + } + loading = true; error = ''; outputText = ''; @@ -108,14 +112,26 @@ systemPrompt = result.systemPrompt; userMessage = result.userMessage; modelLabel = result.modelLabel; + + if (typeof umami !== 'undefined') { + umami.track('convert_success', { style: selectedStyleId, intensity, model: result.modelLabel }); + } } catch (err) { error = err instanceof Error ? err.message : 'Something went wrong'; + + if (typeof umami !== 'undefined') { + umami.track('convert_error', { style: selectedStyleId, intensity, error }); + } } finally { loading = false; } } async function handleCopy() { + if (typeof umami !== 'undefined') { + umami.track('copy_result', { style: selectedStyleId }); + } + try { await navigator.clipboard.writeText(outputText); copied = true; @@ -157,6 +173,7 @@ bind:value={selectedCategoryId} onchange={onCategoryChange} disabled={loading} + data-umami-event="select_category" > {#each categories as cat} @@ -167,7 +184,7 @@
- {#if !selectedCategoryId} {:else if availableStyles.length === 0} @@ -196,6 +213,7 @@ step="1" bind:value={intensity} disabled={loading} + data-umami-event="adjust_intensity" /> Maximum
@@ -240,7 +258,7 @@
- {#if showPrompt}