/** * Umami analytics wrapper — safe server-side, no-op when not configured. * * Events convention: * audio:play | audio:pause | audio:complete | audio:progress * pdf:open | pdf:close * player:open | player:chapter | player:mode * scroll:depth * link:external * cta:click */ export function useTracking() { const runtimeConfig = useRuntimeConfig() const enabled = !!runtimeConfig.public.umamiWebsiteId // ── Core ──────────────────────────────────────────────────────────────── function track(event: string, data?: Record) { if (!import.meta.client || !enabled) return const umami = (window as Record).umami as | { track: (event: string, data?: unknown) => void } | undefined umami?.track(event, data) } // ── Audio ──────────────────────────────────────────────────────────────── function trackAudioPlay(songId: string, songTitle: string, context?: string) { track('audio:play', { song_id: songId, song_title: songTitle, context }) } function trackAudioPause(songId: string, progressPct: number) { track('audio:pause', { song_id: songId, progress_pct: progressPct }) } function trackAudioComplete(songId: string, songTitle: string) { track('audio:complete', { song_id: songId, song_title: songTitle }) } /** Fired at 25 / 50 / 75 % milestones */ function trackAudioProgress(songId: string, milestone: 25 | 50 | 75) { track('audio:progress', { song_id: songId, milestone }) } // ── PDF ────────────────────────────────────────────────────────────────── function trackPdfOpen(trigger?: string) { track('pdf:open', { trigger }) } function trackPdfClose(pagesVisited: number, durationMs: number) { track('pdf:close', { pages_visited: pagesVisited, duration_ms: durationMs }) } // ── BookPlayer ─────────────────────────────────────────────────────────── function trackPlayerOpen(trigger?: string) { track('player:open', { trigger }) } function trackPlayerChapter(chapterSlug: string) { track('player:chapter', { chapter_slug: chapterSlug }) } function trackPlayerMode(mode: 'guided' | 'scroll') { track('player:mode', { mode }) } // ── Navigation & UX ────────────────────────────────────────────────────── function trackScrollDepth(page: string, depth: 25 | 50 | 75 | 100) { track('scroll:depth', { page, depth }) } function trackExternalLink(url: string, label?: string) { const route = useRoute() track('link:external', { url, label, from_page: route.path }) } function trackCta(label: string, target?: string) { const route = useRoute() track('cta:click', { label, target, from_page: route.path }) } return { track, enabled, trackAudioPlay, trackAudioPause, trackAudioComplete, trackAudioProgress, trackPdfOpen, trackPdfClose, trackPlayerOpen, trackPlayerChapter, trackPlayerMode, trackScrollDepth, trackExternalLink, trackCta, } }