diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8e208e4..d22c801 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -12,6 +12,7 @@ import LicenseSuccessModal from './components/ui/LicenseSuccessModal'; import VerificationBanner from './components/ui/VerificationBanner'; import type { FeatureMeta, FeatureGroup, POICategoriesResponse, POICategoryGroup } from './types'; import { fetchWithRetry, apiUrl } from './lib/api'; +import { trackEvent } from './lib/analytics'; import { parseUrlState } from './lib/url-state'; import { INITIAL_VIEW_STATE } from './lib/consts'; import { useTheme } from './hooks/useTheme'; @@ -91,6 +92,10 @@ export default function App() { // Restore from history state (e.g. popstate) if (window.history.state?.page) return window.history.state.page; + // Unknown path — track as 404 + if (window.location.pathname !== '/') { + trackEvent('404', { path: window.location.pathname }); + } return 'home'; }); @@ -122,6 +127,7 @@ export default function App() { ? `${window.location.pathname}?${params.toString()}` : window.location.pathname; window.history.replaceState({}, '', newUrl); + trackEvent('Purchase'); setShowLicenseSuccess(true); refreshAuth(); } diff --git a/frontend/src/components/home/HomePage.tsx b/frontend/src/components/home/HomePage.tsx index 171cd39..7c7f471 100644 --- a/frontend/src/components/home/HomePage.tsx +++ b/frontend/src/components/home/HomePage.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { useFadeInRef } from '../../hooks/useFadeIn'; import HexCanvas from './HexCanvas'; import ScrollStory from './ScrollStory'; @@ -6,6 +6,7 @@ import BottomIllustration from './BottomIllustration'; import { TickerValue } from '../ui/TickerValue'; import { ChevronIcon } from '../ui/icons/ChevronIcon'; import { LogoIcon } from '../ui/icons/LogoIcon'; +import { trackEvent } from '../../lib/analytics'; import type { FeatureMeta } from '../../types'; export default function HomePage({ @@ -30,6 +31,35 @@ export default function HomePage({ const whyRef = useFadeInRef(); const ctaRef = useFadeInRef(); + // Scroll depth tracking + const scrolledSections = useRef(new Set()); + useEffect(() => { + const ids = ['how-it-works', 'demo']; + const observers: IntersectionObserver[] = []; + ids.forEach((id) => { + const el = document.getElementById(id); + if (!el) return; + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting && !scrolledSections.current.has(id)) { + scrolledSections.current.add(id); + trackEvent('Scroll Depth', { section: id }); + } + }, + { threshold: 0.1 } + ); + observer.observe(el); + observers.push(observer); + }); + return () => observers.forEach((o) => o.disconnect()); + }, []); + + // 30s time-on-page event + useEffect(() => { + const timer = setTimeout(() => trackEvent('Time on Page', { seconds: '30' }), 30000); + return () => clearTimeout(timer); + }, []); + return (
@@ -54,13 +84,17 @@ export default function HomePage({