Open danilofuchs opened 5 months ago
I checked this out just now with the example app in the repository and no issues. Does this occur on the latest version?
I checked this out just now with the example app in the repository and no issues. Does this occur on the latest version?
It does occur on the latest version. I'm having a bad time debugging this because of the minified code. I will investigate further next week
Hi @benjackwhite and team,
My team ran into a similar problem this week trying to upgrade from a very old posthog-js version (1.67) and we dug pretty deep into the problem.
The reason you are not able to reproduce the issue using the Next.js example app in this repository is because the example app initializes the PostHog client on its own and then passes that client to <PostHogProvider>
. The example app does not actually initialize the PostHog client during prerendering because the initialization is wrapped in a useEffect
.
@danilofuchs's reproduction passes the API key to PostHogProvider
, and PostHogProvider
initializes the PostHog client in a useMemo
. This means posthog-js
's client gets initialized during prerendering on the server.
I tracked down PR #705 where the client initialization was moved from a useEffect
to a useMemo
v1.68.3. Though that change did not visibly break things, it does break a major rule of useMemo
:
That PR is going to need to be reverted if people are going to be able to use posthog-js/react
to initialize the PostHog client for them in apps that make use of server-side prerendering. Even in apps that do not server-side prerender, I would not be comfortable having posthog-js/react
initialize the PostHog client because it is causing the component to have side effects during rendering (e.g. API requests, changing the state of the PostHog client). The correct place for those types of changes in React is within a useEffect
, as the posthog-js client was doing in versions prior to v1.68.3.
Some potentially related tickets:
Moving the PostHog client init back to a useEffect will help all of these issues, if not completely solve them.
Until posthog-js/react gets fixed, my recommended workaround is to change your code to something like this @danilofuchs:
import { useUser } from "@clerk/nextjs";
import { PostHogProvider as Provider, usePostHog } from "posthog-js/react";
import { useEffect } from "react";
import { env } from "~/env.js";
interface Props {
children: React.ReactNode;
}
export const PostHogProvider = ({ children }: Props) => {
const [postHogClient, setPostHogClient] = useState<PostHog | undefined>();
useEffect(() => {
if (postHogClient) {
return;
}
posthog.init(env.NEXT_PUBLIC_POSTHOG_KEY);
setPostHogClient(posthog);
}, []);
return (
<Provider client={postHogClient}>
<PostHogUserSync />
{children}
</Provider>
);
};
// ...
Thanks y'all for all you do!
Great investigation @lightster!
I reviewed the official documentation for Pages Router and they recommend initializing in client only:
https://posthog.com/docs/libraries/next-js#pages-router
This solved the issue for us, but I believe PostHogProvider
should initialize the SDK correctly out of the box
Bug description
Using Next.js Pages Router, PostHog/React crashes build for static pages
posthog-js >= 1.112.0
(I tested all 1.111.x builds and they work as expected, anything from 1.112.0 and above is broken for us)
How to reproduce
interface Props { children: React.ReactNode; }
export const PostHogProvider = ({ children }: Props) => { return (
); };
const PostHogUserSync = () => { const postHog = usePostHog(); const { user, isLoaded, isSignedIn } = useUser();
useEffect(() => { if (user && isLoaded && isSignedIn) { postHog.identify(user.id, { email: user.primaryEmailAddress?.emailAddress, companyId: user.publicMetadata.companyId, role: user.publicMetadata.role, }); }
}, [user, isLoaded, isSignedIn, postHog]);
return null; };
next build
Additional context
L
is minified, appears to be an HTTP fetcher , probably related to https://github.com/PostHog/posthog-js/pull/1055 from 1.112.0Thank you for your bug report – we love squashing them!