import { Analytics, AnalyticsBrowser } from "@segment/analytics-next"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { AnalyticsContext } from "./context"; import { AnalyticsContextValue } from "./types"; export interface AnalyticsProviderProps { segmentWriteToken?: string; blockedUserAgents?: string[]; } export const AnalyticsProvider = ({ segmentWriteToken, blockedUserAgents, children, }: React.PropsWithChildren) => { const [isReady, setIsReady] = useState(false); const isBlockedUserAgent = useMemo(() => { return ( !!blockedUserAgents && typeof window !== "undefined" && !!window?.navigator?.userAgent && blockedUserAgents.includes(window?.navigator?.userAgent) ); }, [blockedUserAgents?.join("")]); const analytics = useMemo(() => { if (!segmentWriteToken) return; return AnalyticsBrowser.load({ writeKey: segmentWriteToken }); }, [segmentWriteToken]); useEffect(() => { if (!analytics) return; analytics.ready(() => setIsReady(true)); }, [analytics]); const identify = useCallback( (...args: Parameters) => { if (!analytics || isBlockedUserAgent) return; analytics.identify(...args); }, [analytics, isBlockedUserAgent] ); const alias = useCallback( (...args: Parameters) => { if (!analytics) return; analytics.alias(...args); }, [analytics] ); const trackPageView = useCallback( (...args: Parameters) => { if (!analytics) return; analytics.page(...args); }, [analytics] ); const track = useCallback( (...args: Parameters) => { if (!analytics || isBlockedUserAgent) return; analytics.track(...args); }, [analytics, isBlockedUserAgent] ); const reset = useCallback(() => { if (!analytics) return; analytics.reset(); }, [analytics]); const contextValue: AnalyticsContextValue = { analytics, analyticsReady: isReady, identify, alias, trackPageView, track, reset, }; const value: AnalyticsContextValue = useMemo( () => contextValue, [...Object.values(contextValue)] ); return ( {children} ); };