feat: PostHog 集成\

1.  安装依赖: posthog-js@^1.280.1
  2.  创建核心文件:
    - src/lib/posthog.js - PostHog SDK 封装(271 行)
    - src/lib/constants.js - 事件常量定义(AARRR 框架)
    - src/hooks/usePostHog.js - PostHog React Hook
    - src/hooks/usePageTracking.js - 页面追踪 Hook
    - src/components/PostHogProvider.js - Provider 组件
  3.  集成到应用:
    - 修改 src/App.js,在最外层添加 <PostHogProvider>
    - 自动追踪所有页面浏览
  4.  配置环境变量:
    - 在 .env 添加 PostHog 配置项
    - REACT_APP_POSTHOG_KEY 留空,需要用户填写
  5.  创建文档: POSTHOG_INTEGRATION.md 包含完整的使用说明
This commit is contained in:
zdl
2025-10-28 20:09:21 +08:00
parent 542b20368e
commit 6506cb222b
7 changed files with 892 additions and 27 deletions

View File

@@ -0,0 +1,55 @@
// src/hooks/usePageTracking.js
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';
import posthog from 'posthog-js';
/**
* Custom hook for automatic page view tracking with PostHog
*
* @param {Object} options - Configuration options
* @param {boolean} options.enabled - Whether tracking is enabled
* @param {Function} options.getProperties - Function to get custom properties for each page view
*/
export const usePageTracking = ({ enabled = true, getProperties } = {}) => {
const location = useLocation();
const previousPathRef = useRef('');
useEffect(() => {
if (!enabled) return;
// Get the current path
const currentPath = location.pathname + location.search;
// Skip if it's the same page (prevents duplicate tracking)
if (previousPathRef.current === currentPath) {
return;
}
// Update the previous path
previousPathRef.current = currentPath;
// Get custom properties if function provided
const customProperties = getProperties ? getProperties(location) : {};
// Track page view with PostHog
if (posthog && posthog.__loaded) {
posthog.capture('$pageview', {
$current_url: window.location.href,
path: location.pathname,
search: location.search,
hash: location.hash,
...customProperties,
});
// Log in development
if (process.env.NODE_ENV === 'development') {
console.log('📊 PostHog $pageview:', {
path: location.pathname,
...customProperties,
});
}
}
}, [location, enabled, getProperties]);
};
export default usePageTracking;

101
src/hooks/usePostHog.js Normal file
View File

@@ -0,0 +1,101 @@
// src/hooks/usePostHog.js
import { useCallback } from 'react';
import {
getPostHog,
trackEvent,
trackPageView,
identifyUser,
setUserProperties,
resetUser,
optIn,
optOut,
hasOptedOut,
getFeatureFlag,
isFeatureEnabled,
} from '../lib/posthog';
/**
* Custom hook to access PostHog functionality
* Provides convenient methods for tracking events and managing user sessions
*
* @returns {object} PostHog methods
*/
export const usePostHog = () => {
// Get PostHog instance
const posthog = getPostHog();
// Track custom event
const track = useCallback((eventName, properties = {}) => {
trackEvent(eventName, properties);
}, []);
// Track page view
const trackPage = useCallback((pagePath, properties = {}) => {
trackPageView(pagePath, properties);
}, []);
// Identify user
const identify = useCallback((userId, userProperties = {}) => {
identifyUser(userId, userProperties);
}, []);
// Set user properties
const setProperties = useCallback((properties) => {
setUserProperties(properties);
}, []);
// Reset user session (logout)
const reset = useCallback(() => {
resetUser();
}, []);
// Opt out of tracking
const optOutTracking = useCallback(() => {
optOut();
}, []);
// Opt in to tracking
const optInTracking = useCallback(() => {
optIn();
}, []);
// Check if user has opted out
const isOptedOut = useCallback(() => {
return hasOptedOut();
}, []);
// Get feature flag value
const getFlag = useCallback((flagKey, defaultValue = false) => {
return getFeatureFlag(flagKey, defaultValue);
}, []);
// Check if feature is enabled
const isEnabled = useCallback((flagKey) => {
return isFeatureEnabled(flagKey);
}, []);
return {
// Core PostHog instance
posthog,
// Tracking methods
track,
trackPage,
// User management
identify,
setProperties,
reset,
// Privacy controls
optOut: optOutTracking,
optIn: optInTracking,
isOptedOut,
// Feature flags
getFlag,
isEnabled,
};
};
export default usePostHog;