diff --git a/web/.env.example b/web/.env.example
index 8eefbb5..008df45 100644
--- a/web/.env.example
+++ b/web/.env.example
@@ -16,4 +16,7 @@ SPACES_CDN_FORCE_PATH_STYLE="true"
MODAL_BUILDER_URL=
JWT_SECRET="openssl rand -hex 32"
-PLAUSIBLE_DOMAIN=
\ No newline at end of file
+PLAUSIBLE_DOMAIN=
+
+NEXT_PUBLIC_POSTHOG_KEY="your-api-key"
+NEXT_PUBLIC_POSTHOG_HOST="your-ph-address"
diff --git a/web/bun.lockb b/web/bun.lockb
index 8ca5312..6f53ecc 100755
Binary files a/web/bun.lockb and b/web/bun.lockb differ
diff --git a/web/package.json b/web/package.json
index 290c261..fd3fa9a 100644
--- a/web/package.json
+++ b/web/package.json
@@ -76,6 +76,8 @@
"next-themes": "^0.2.1",
"next-usequerystate": "^1.13.2",
"pg": "^8.11.3",
+ "posthog-js": "^1.100.0",
+ "posthog-node": "^3.5.0",
"react": "^18",
"react-day-picker": "^8.9.1",
"react-dom": "^18",
diff --git a/web/src/app/(app)/PostHogPageView.tsx b/web/src/app/(app)/PostHogPageView.tsx
new file mode 100644
index 0000000..3c05d4b
--- /dev/null
+++ b/web/src/app/(app)/PostHogPageView.tsx
@@ -0,0 +1,29 @@
+// app/PostHogPageView.tsx
+'use client'
+
+import { usePathname, useSearchParams } from "next/navigation";
+import { useEffect } from "react";
+import { usePostHog } from 'posthog-js/react';
+
+export default function PostHogPageView() {
+ const pathname = usePathname();
+ const searchParams = useSearchParams();
+ const posthog = usePostHog();
+ // Track pageviews
+ useEffect(() => {
+ if (pathname && posthog) {
+ let url = window.origin + pathname
+ if (searchParams.toString()) {
+ url = url + `?${searchParams.toString()}`
+ }
+ posthog.capture(
+ '$pageview',
+ {
+ '$current_url': url,
+ }
+ )
+ }
+ }, [pathname, searchParams, posthog])
+
+ return null
+}
diff --git a/web/src/app/(app)/layout.tsx b/web/src/app/(app)/layout.tsx
index ae372fe..332b36c 100644
--- a/web/src/app/(app)/layout.tsx
+++ b/web/src/app/(app)/layout.tsx
@@ -7,6 +7,13 @@ import meta from "next-gen/config";
import PlausibleProvider from "next-plausible";
import { Inter } from "next/font/google";
import { Toaster } from "sonner";
+import { PHProvider } from "./providers";
+
+import dynamic from "next/dynamic";
+
+const PostHogPageView = dynamic(() => import("./PostHogPageView"), {
+ ssr: false,
+});
const inter = Inter({ subsets: ["latin"] });
@@ -39,20 +46,23 @@ export default function RootLayout({