diff --git a/autogpt_platform/frontend/src/app/providers.tsx b/autogpt_platform/frontend/src/app/providers.tsx
index 2585ae2a6c..267814e7c2 100644
--- a/autogpt_platform/frontend/src/app/providers.tsx
+++ b/autogpt_platform/frontend/src/app/providers.tsx
@@ -1,38 +1,21 @@
"use client";
import { TooltipProvider } from "@/components/atoms/Tooltip/BaseTooltip";
-import {
- PostHogPageViewTracker,
- PostHogUserTracker,
-} from "@/components/monitor/PostHogUserTracker";
import { SentryUserTracker } from "@/components/monitor/SentryUserTracker";
import { BackendAPIProvider } from "@/lib/autogpt-server-api/context";
import { getQueryClient } from "@/lib/react-query/queryClient";
import CredentialsProvider from "@/providers/agent-credentials/credentials-provider";
import OnboardingProvider from "@/providers/onboarding/onboarding-provider";
+import {
+ PostHogPageViewTracker,
+ PostHogProvider,
+ PostHogUserTracker,
+} from "@/providers/posthog/posthog-provider";
import { LaunchDarklyProvider } from "@/services/feature-flags/feature-flag-provider";
-import { PostHogProvider as PHProvider } from "@posthog/react";
import { QueryClientProvider } from "@tanstack/react-query";
import { ThemeProvider, ThemeProviderProps } from "next-themes";
import { NuqsAdapter } from "nuqs/adapters/next/app";
-import posthog from "posthog-js";
-import { Suspense, useEffect } from "react";
-
-function PostHogProvider({ children }: { children: React.ReactNode }) {
- useEffect(() => {
- if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
- posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
- api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
- defaults: "2025-11-30",
- capture_pageview: false,
- capture_pageleave: true,
- autocapture: true,
- });
- }
- }, []);
-
- return {children};
-}
+import { Suspense } from "react";
export function Providers({ children, ...props }: ThemeProviderProps) {
const queryClient = getQueryClient();
diff --git a/autogpt_platform/frontend/src/components/monitor/PostHogUserTracker.tsx b/autogpt_platform/frontend/src/providers/posthog/posthog-provider.tsx
similarity index 61%
rename from autogpt_platform/frontend/src/components/monitor/PostHogUserTracker.tsx
rename to autogpt_platform/frontend/src/providers/posthog/posthog-provider.tsx
index 470804abf1..4fb6edc8e7 100644
--- a/autogpt_platform/frontend/src/components/monitor/PostHogUserTracker.tsx
+++ b/autogpt_platform/frontend/src/providers/posthog/posthog-provider.tsx
@@ -1,20 +1,27 @@
"use client";
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
+import { PostHogProvider as PHProvider } from "@posthog/react";
import { usePathname, useSearchParams } from "next/navigation";
import posthog from "posthog-js";
import { useEffect, useRef } from "react";
-/**
- * PostHogUserTracker component identifies users in PostHog for analytics.
- * This component should be placed high in the component tree to ensure user
- * identification happens as soon as the user logs in.
- *
- * It automatically:
- * - Identifies the user when they log in (linking anonymous to authenticated)
- * - Resets PostHog when a user logs out
- * - Updates identification when user data changes
- */
+export function PostHogProvider({ children }: { children: React.ReactNode }) {
+ useEffect(() => {
+ if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
+ posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ defaults: "2025-11-30",
+ capture_pageview: false,
+ capture_pageleave: true,
+ autocapture: true,
+ });
+ }
+ }, []);
+
+ return {children};
+}
+
export function PostHogUserTracker() {
const { user, isUserLoading } = useSupabase();
const previousUserIdRef = useRef(null);
@@ -23,7 +30,6 @@ export function PostHogUserTracker() {
if (isUserLoading) return;
if (user) {
- // Only identify if we haven't already identified this user
if (previousUserIdRef.current !== user.id) {
posthog.identify(user.id, {
email: user.email,
@@ -32,7 +38,6 @@ export function PostHogUserTracker() {
previousUserIdRef.current = user.id;
}
} else if (previousUserIdRef.current !== null) {
- // User logged out - reset PostHog to generate new anonymous ID
posthog.reset();
previousUserIdRef.current = null;
}
@@ -41,11 +46,6 @@ export function PostHogUserTracker() {
return null;
}
-/**
- * PostHogPageViewTracker captures page views on route changes in Next.js App Router.
- * The default PostHog capture_pageview only works for initial page loads.
- * This component ensures soft navigations (client-side route changes) are also tracked.
- */
export function PostHogPageViewTracker() {
const pathname = usePathname();
const searchParams = useSearchParams();