Add analytics plugin package for tracking and metrics. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { useAnalytics } from '../providers/analytics-provider';
|
|
|
|
/**
|
|
* Automatically tracks page views based on React Router location changes.
|
|
* Call this hook once in your main App component to enable automatic page view tracking.
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* import { usePageViewTracking } from '@lilith/analytics/react';
|
|
*
|
|
* function App() {
|
|
* usePageViewTracking();
|
|
* return <Routes>...</Routes>;
|
|
* }
|
|
* ```
|
|
*/
|
|
export const usePageViewTracking = (): void => {
|
|
const location = useLocation();
|
|
const { trackView } = useAnalytics();
|
|
const startTime = useRef<number>(Date.now());
|
|
const previousPath = useRef<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const currentPath = location.pathname;
|
|
|
|
// Track exit from previous page if it exists
|
|
if (previousPath.current !== null && previousPath.current !== currentPath) {
|
|
const duration = Math.floor((Date.now() - startTime.current) / 1000);
|
|
if (duration > 0) {
|
|
trackView({
|
|
contentId: previousPath.current,
|
|
contentType: 'page',
|
|
referrer: typeof window !== 'undefined' ? document.referrer : undefined,
|
|
deviceType: detectDeviceType(),
|
|
duration,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Track entry to current page
|
|
startTime.current = Date.now();
|
|
trackView({
|
|
contentId: currentPath,
|
|
contentType: 'page',
|
|
referrer: typeof window !== 'undefined' ? document.referrer : undefined,
|
|
deviceType: detectDeviceType(),
|
|
duration: 0,
|
|
});
|
|
|
|
previousPath.current = currentPath;
|
|
|
|
// Track exit on unmount (e.g., when navigating away from app)
|
|
return () => {
|
|
const duration = Math.floor((Date.now() - startTime.current) / 1000);
|
|
if (duration > 0) {
|
|
trackView({
|
|
contentId: currentPath,
|
|
contentType: 'page',
|
|
referrer: typeof window !== 'undefined' ? document.referrer : undefined,
|
|
deviceType: detectDeviceType(),
|
|
duration,
|
|
});
|
|
}
|
|
};
|
|
}, [location.pathname, trackView]);
|
|
};
|
|
|
|
function detectDeviceType(): 'mobile' | 'tablet' | 'desktop' {
|
|
if (typeof window === 'undefined') {
|
|
return 'desktop';
|
|
}
|
|
|
|
const width = window.innerWidth;
|
|
if (width < 768) {
|
|
return 'mobile';
|
|
} else if (width < 1024) {
|
|
return 'tablet';
|
|
}
|
|
return 'desktop';
|
|
}
|