dograh/ui/src/components/PostHogIdentify.tsx

76 lines
2.7 KiB
TypeScript

'use client';
import posthog from 'posthog-js';
import { useEffect } from 'react';
import { PostHogEvent } from '@/constants/posthog-events';
import { useAuth } from '@/lib/auth';
/**
* PostHogIdentify
* ---------------
* Calls `posthog.identify` once the authenticated user object is available,
* using the Stack Auth user ID as distinct_id with email and name as properties.
*
* Rendered in the root layout (`app/layout.tsx`) so it fires on every session
* for every logged-in user.
*/
export default function PostHogIdentify() {
const { user } = useAuth();
useEffect(() => {
if (user) {
const identify = () => {
try {
// Stack Auth users expose primaryEmail/displayName,
// local users expose email/name — handle both.
const email =
'primaryEmail' in user ? user.primaryEmail :
'email' in user ? user.email :
undefined;
const name =
'displayName' in user ? user.displayName :
'name' in user ? user.name :
undefined;
// Use provider_id as distinct_id to match backend PostHog events.
// Stack Auth users: user.id is already the provider_id.
// OSS users: provider_id is returned from the auth API.
const distinctId =
'provider_id' in user && user.provider_id
? String(user.provider_id)
: String(user.id);
posthog.identify(distinctId, {
...(email && { email }),
...(name && { name }),
});
posthog.capture(PostHogEvent.SIGNED_IN);
} catch (err) {
console.warn('Failed to identify user in PostHog', err);
}
};
if (posthog.__loaded) {
identify();
} else {
// PostHog initializes async — retry until ready
let attempts = 0;
const interval = setInterval(() => {
attempts++;
if (posthog.__loaded) {
identify();
clearInterval(interval);
} else if (attempts >= 20) {
clearInterval(interval);
}
}, 200);
return () => clearInterval(interval);
}
} else {
posthog.reset();
}
}, [user]);
return null;
}