import { datadogRum } from "@datadog/browser-rum"; import { useEffect, useState } from "react"; import type { User } from "@dndbeyond/authentication-lib-js"; import config from "~/config"; import { useConsent } from "~/hooks/useConsent"; const isDndbeyondUrl = (url: string): boolean => { try { const { protocol, hostname } = new URL(url); return ( protocol === "https:" && (hostname === "dndbeyond.com" || hostname.endsWith(".dndbeyond.com")) ); } catch { return false; } }; export const useDatadogRum = (user: User | null) => { const [hasConsent, setHasConsent] = useState(false); const [isInitialized, setIsInitialized] = useState(false); const environment = config.environment; const version = config.version.replace(/@dndbeyond\/character-app@/, ""); // example: 1.70.116 const { setupAnalyticsConsentListener } = useConsent(); useEffect(() => { const unsubscribe = setupAnalyticsConsentListener(setHasConsent); return () => { unsubscribe(); }; }, [setupAnalyticsConsentListener]); useEffect(() => { if (datadogRum.getInternalContext()) { return; } try { datadogRum.init({ applicationId: "2cfa3248-a632-4f5b-bf9e-aafa18dc69ae", // Not a secret, safe to include in client code clientToken: "pub940bbbc614a4ae3ab0c872fdad597554", // Not a secret, safe to include in client code site: "datadoghq.com", service: "characters-app", env: environment === "production" ? "live" : environment, version: `${version}`, sessionSampleRate: environment === "production" ? 10 : 100, sessionReplaySampleRate: environment === "production" ? 1 : 10, traceContextInjection: "sampled", traceSampleRate: 10, trackingConsent: "not-granted", // Start with no consent, will update when consent status is known trackUserInteractions: true, trackResources: true, trackLongTasks: true, defaultPrivacyLevel: "mask-user-input", allowedTracingUrls: [isDndbeyondUrl], }); setIsInitialized(true); } catch (error) { console.warn("Datadog RUM failed to initialize:", error); } }, [environment]); useEffect(() => { if (!isInitialized) { return; } if (!user) { datadogRum.clearUser(); return; } datadogRum.setUser({ id: `${user.id ?? ""}`, name: `${user.name ?? ""}`, sub_tier: `${user.subscriptionTier ?? ""}`, }); }, [user, isInitialized]); useEffect(() => { if (!isInitialized) { return; } datadogRum.setTrackingConsent(hasConsent ? "granted" : "not-granted"); }, [hasConsent, isInitialized]); };