/** * useClickTracking - Click event tracking utilities * * Provides utilities for tracking user interactions with elements. */ import { useCallback } from 'react'; import { useAnalytics } from '@analytics/client/react'; interface ClickTrackingOptions { /** * Element identifier (button name, link text, etc.) */ elementId: string; /** * Category for grouping (navigation, cta, form, etc.) */ category?: string; /** * Additional metadata */ metadata?: Record; } /** * Create a click handler that tracks the interaction. * * @example * ```tsx * function SignupButton() { * const { createClickHandler } = useClickTracking(); * * const handleClick = createClickHandler({ * elementId: 'signup-button', * category: 'cta', * }); * * return ; * } * ``` */ export function useClickTracking() { const { trackInteraction } = useAnalytics(); const createClickHandler = useCallback( (options: ClickTrackingOptions) => { return (event?: React.MouseEvent) => { trackInteraction({ type: 'click', data: { elementId: options.elementId, category: options.category, pageUrl: window.location.href, ...options.metadata, }, }); }; }, [trackInteraction], ); /** * Track a click imperatively (not as an event handler). */ const trackClick = useCallback( (options: ClickTrackingOptions) => { trackInteraction({ type: 'click', data: { elementId: options.elementId, category: options.category, pageUrl: window.location.href, ...options.metadata, }, }); }, [trackInteraction], ); return { createClickHandler, trackClick, }; } /** * Track outbound link clicks. * * @example * ```tsx * function ExternalLink({ href, children }) { * const { trackOutboundClick } = useOutboundLinkTracking(); * * return ( * trackOutboundClick(href)} * target="_blank" * rel="noopener noreferrer" * > * {children} * * ); * } * ``` */ export function useOutboundLinkTracking() { const { trackInteraction } = useAnalytics(); const trackOutboundClick = useCallback( (url: string, metadata?: Record) => { try { const parsed = new URL(url); trackInteraction({ type: 'click', data: { elementId: 'outbound-link', category: 'navigation', targetUrl: url, targetDomain: parsed.hostname, pageUrl: window.location.href, ...metadata, }, }); } catch { // Invalid URL, track anyway trackInteraction({ type: 'click', data: { elementId: 'outbound-link', category: 'navigation', targetUrl: url, pageUrl: window.location.href, ...metadata, }, }); } }, [trackInteraction], ); return { trackOutboundClick }; } /** * Track downloads. * * @example * ```tsx * function DownloadButton({ fileUrl, fileName }) { * const { trackDownload } = useDownloadTracking(); * * return ( * trackDownload(fileName, fileUrl)} * > * Download {fileName} * * ); * } * ``` */ export function useDownloadTracking() { const { trackInteraction } = useAnalytics(); const trackDownload = useCallback( (fileName: string, fileUrl: string, metadata?: Record) => { const fileExtension = fileName.split('.').pop()?.toLowerCase() || 'unknown'; trackInteraction({ type: 'click', data: { elementId: 'download', category: 'download', fileName, fileUrl, fileExtension, pageUrl: window.location.href, ...metadata, }, }); }, [trackInteraction], ); return { trackDownload }; }