Bootstrap posthog-js with the persisted install ID from the server, forward distinctId to API routes, and restructure feedback traces to use chronological conversation order.
68 lines
1.6 KiB
TypeScript
68 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import posthog from "posthog-js";
|
|
import { PostHogProvider as PHProvider } from "posthog-js/react";
|
|
import { useEffect, useRef } from "react";
|
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
|
|
const POSTHOG_KEY = process.env.NEXT_PUBLIC_POSTHOG_KEY || "";
|
|
const POSTHOG_HOST = "https://us.i.posthog.com";
|
|
|
|
let initialized = false;
|
|
|
|
function initPostHog(anonymousId?: string) {
|
|
if (initialized || !POSTHOG_KEY || typeof window === "undefined") return;
|
|
|
|
posthog.init(POSTHOG_KEY, {
|
|
api_host: POSTHOG_HOST,
|
|
capture_pageview: false,
|
|
capture_pageleave: true,
|
|
persistence: "memory",
|
|
autocapture: false,
|
|
disable_session_recording: true,
|
|
person_profiles: "identified_only",
|
|
bootstrap: anonymousId
|
|
? { distinctID: anonymousId, isIdentifiedID: false }
|
|
: undefined,
|
|
});
|
|
initialized = true;
|
|
}
|
|
|
|
function PageviewTracker() {
|
|
const pathname = usePathname();
|
|
const searchParams = useSearchParams();
|
|
|
|
useEffect(() => {
|
|
if (!initialized) return;
|
|
const url = pathname + (searchParams?.toString() ? `?${searchParams.toString()}` : "");
|
|
posthog.capture("$pageview", { $current_url: url });
|
|
}, [pathname, searchParams]);
|
|
|
|
return null;
|
|
}
|
|
|
|
export function PostHogProvider({
|
|
children,
|
|
anonymousId,
|
|
}: {
|
|
children: React.ReactNode;
|
|
anonymousId?: string;
|
|
}) {
|
|
const initRef = useRef(false);
|
|
|
|
useEffect(() => {
|
|
if (initRef.current) return;
|
|
initRef.current = true;
|
|
initPostHog(anonymousId);
|
|
}, [anonymousId]);
|
|
|
|
if (!POSTHOG_KEY) return <>{children}</>;
|
|
|
|
return (
|
|
<PHProvider client={posthog}>
|
|
<PageviewTracker />
|
|
{children}
|
|
</PHProvider>
|
|
);
|
|
}
|