posthog-js icon indicating copy to clipboard operation
posthog-js copied to clipboard

"posthog was already loaded elsewhere"

Open olliejm opened this issue 2 years ago • 12 comments

I'm having an issue with posthog logging this error. we are using gatsby but not the gatsby plugin, current posthog version is 1.69.0. we're initialising in gatsby-browser.tsx with:

export const wrapRootElement: GatsbyBrowser['wrapRootElement'] = ({ element }) => (
  <PostHogProvider
    apiKey={apiKey}
    options={posthogOptions}
  >
    {element}
  </PostHogProvider>
);

The simply importing usePosthog and useFeatureFlagEnabled in a few places. I can't currently see how it would be loaded twice?

olliejm avatar Jul 05 '23 12:07 olliejm

Is the provider only loaded once?

neilkakkar avatar Jul 06 '23 10:07 neilkakkar

Yeah in gatsby-browser.tsx file as part of wrapRootElement, is the only place we load it. We also export the same wrapRootElement in gatsby-ssr, but removing provider from SSR root did not seem to change anything.

I can try and make a minimal repro next week but I'm currently travelling. -------- Original Message -------- On 6 Jul 2023, 11:16, Neil Kakkar wrote:

Is the provider only loaded once?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

olliejm avatar Jul 06 '23 10:07 olliejm

fwiw I am seeing this issue too. I just bumped posthog-js from ^1.51.5 to ^1.76.0 and started getting this issue when server-side rendering our Next.js app. I verified that the provider component is only used once in _app.js

jon-spover avatar Aug 14 '23 19:08 jon-spover

Does it happen in production? I'm wondering if the useMemo in:

https://github.com/PostHog/posthog-js/blob/79bfc90b993bbc683c1f251b8834130dcd420af1/react/src/context/PostHogProvider.tsx

triggers twice due to strict mode (https://react.dev/reference/react/StrictMode#fixing-bugs-found-by-double-rendering-in-development) which happens in development and tries to initiate posthog twice.

charliemday avatar Aug 30 '23 14:08 charliemday

Following up on Charlie's comments, I am getting the same warning message in Production.

dchadcluff avatar Dec 01 '23 18:12 dchadcluff

Pretty sure this is due to React StrictMode

danilofuchs avatar Jan 29 '24 19:01 danilofuchs

I know this is already a year old, however it's still open, and I'd like to add another report to note that this is still a problem:

Environment

  • react 18.3.1
  • posthog-js 1.146.0

StrictMode

We are using React's StrictMode, however I have observed this message in production. I see no other evidence of StrictMode's side effects in production (nothing double renders, no effects are called twice, etc.). This seems isolated to PostHog.

Further, if I remove StrictMode, I can still reproduce this behavior.

Initialization

PostHog was initialized using PostHogProvider, exactly as described in the docs

import React from "react";

import constants from "@constants";
import { PostHogProvider } from "posthog-js/react";
import ReactDOM from "react-dom/client";

import App from "./App";

import "./index.css";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <PostHogProvider
      apiKey={constants.POSTHOG.API_KEY}
      options={{ api_host: constants.POSTHOG.API_HOST }}
    >
      <App />
    </PostHogProvider>
  </React.StrictMode>,
);

The only other imports of PostHog in my app are imports of usePostHog. A grep of the project reveals no other reference to PostHog at all outside of posthog?.capture calls. An example of this:

import { useEffect } from "react";

import constants from "@constants";
import { usePostHog } from "posthog-js/react";
import { useLocation } from "react-router-dom";

export default function AnalyticsReporter(): null {
  const location = useLocation();
  const posthog = usePostHog();

  useEffect(() => {
    if (constants.REPORT_ANALYTICS) {
      // send pageview event to posthog
      posthog?.capture("$pageview");
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location]);

  return null;
}

Expected Outcome

PostHog's client should work as documented, without an exception in console

Actual Outcome

We observe [PostHog.js] was already loaded elsewhere. This may cause issues. in the console in 100% of cases in our production environment.

image

wastrachan avatar Jul 11 '24 15:07 wastrachan

Yeah we still get this issue in production as well, not sure exact posthog version off the top of my head but it was the latest as of a few months ago and this issue has stayed consistently since the time I opened the ticket

olliejm avatar Jul 11 '24 20:07 olliejm

using posthog 1.147.0 this error occurs in production. we have confirmed all the things you would recommend: the context is only loaded once and posthog is not imported beyond usePostHog hook.

this looks to me like it is not checking if it already exsists when usePostHog is invoked (something the usehooks-ts package useScript hook does automatically)

rj-wowza avatar Aug 01 '24 22:08 rj-wowza

[PostHog.js] was already loaded elsewhere. This may cause issues. I just wanted to confirm that the issue persists and goes away if React.StrictMode is commented out, which isn't desired.

Nikoobox avatar Aug 04 '24 03:08 Nikoobox

image

# package.js
"posthog-js": "^1.157.2",
"next": "^14.0.1",
# next.config.js
 reactStrictMode: false

unable to use posthog given this error

VDuda avatar Aug 26 '24 18:08 VDuda

Still getting this error as well, any updates?

rjzheng avatar Oct 23 '24 23:10 rjzheng

A good alternative is to just use the web js implementation and load the plugin manually rather than using the Provider, which seems to not have any drawbacks: https://posthog.com/docs/libraries/js

import posthog from 'posthog-js'
posthog.init(API_KEY, { api_host: 'https://us.i.posthog.com' })

jgentes avatar Jan 07 '25 04:01 jgentes

https://github.com/PostHog/posthog-js/issues/723#issuecomment-2574392522 honestly this just works, plus we get to remove a context so i'm here for it.

i confirmed the usePosthog() hook continues to work for capturing events without the context as long as i init when the app loads (for my setup of course)

// post-hog-init.ts

- import { usePostHog, PostHog } from 'posthog-js/react';
+ import posthogCjs, { type PostHogConfig, type PostHog } from 'posthog-js';

- const posthog: PostHog = usePostHog()
+ const posthog: PostHog = posthogCjs

useEffect(() => {
+ posthog.init(API_KEY, options)  
  if (posthog.__loaded) {
    setIsLoaded(true)
    posthog.identify() 
  }
}, [user])

return isLoaded

rj-wowza avatar Jan 07 '25 22:01 rj-wowza

Hey, everyone!

I have a proposed fix in https://github.com/PostHog/posthog-js/pull/1676. This attempts to detect React.StrictMode and skips logging the error in that situation.

I believe owning the initialization is better practice (i.e. you control calling posthog.init and you pass your own initialized client to the provider), but we'll keep supporting apiKey and options for the foreseeable future, so this fix is welcome.

You are free to comment in the PR if you disagree with the proposed solution. We intend to have this merged by EOW.

rafaeelaudibert avatar Jan 22 '25 18:01 rafaeelaudibert

Had the same problem, and fixed it by moving the PostHog provider up in the hierarchy. I guess I was accessing PostHog outside the reach of its provider.

billvog avatar Jan 27 '25 12:01 billvog

@billvog can you explain what you mean by moving it up in the hierarchy?

alexis-wei avatar Jan 30 '25 18:01 alexis-wei

Still seeing this issue on version 1.215.3. I don't have strict mode enabled and the posthog provider is the topmost component in my app 😕

jperezr21 avatar Feb 04 '25 21:02 jperezr21

@alexis-wei Before:

<SomeProvider>
  <PostHogProvider>
  ...
  </PostHogProvider>
</SomeProvider>

After:

<PostHogProvider>
  <SomeProvider>
  ...
  </SomeProvider>
</PostHogProvider>

Perhaps something in the SomeProvider was trying to access the PostHog client.

billvog avatar Feb 05 '25 12:02 billvog

@rafaeelaudibert I am still getting this error. Really simple usecase:

const root = createRoot(document.getElementById("root")!);

root.render(
    <StrictMode>
        <PostHogProvider apiKey={postHogApiKey} options={POSTHOG_OPTIONS}>
            <RouterProvider router={router} />
        </PostHogProvider>
    </StrictMode>
);

[PostHog.js] `posthog` was already loaded elsewhere.

joesaunderson avatar Feb 13 '25 16:02 joesaunderson

I was also experiencing this issue. I checked the docs for nextjs config and they now have been updated. Wrapping posthog.init in a useEffect on the posthog client provider solved it for me.

https://posthog.com/docs/libraries/next-js#router-specific-instructions

jperezr21 avatar Feb 13 '25 20:02 jperezr21

Additional context... we are not using Next.js (but React Router)

joesaunderson avatar Feb 13 '25 20:02 joesaunderson

I was also experiencing this issue. I checked the docs for nextjs config and they now have been updated. Wrapping posthog.init in a useEffect on the posthog client provider solved it for me.

https://posthog.com/docs/libraries/next-js#router-specific-instructions

Thank you, this solved my issue.

xKelvin avatar Feb 15 '25 02:02 xKelvin

I was also experiencing this issue. I checked the docs for nextjs config and they now have been updated. Wrapping posthog.init in a useEffect on the posthog client provider solved it for me.

https://posthog.com/docs/libraries/next-js#router-specific-instructions

Thanks a lot - this solved my issue!

MaxPace-fp avatar Feb 19 '25 07:02 MaxPace-fp

Still seeing this issue, with:

<StrictMode>
<PostHogProvider
    apiKey={env.publicPostHogApiKey()}
    options={postHogOptions}>

I also tried:

posthog.init(env.publicPostHogApiKey(), postHogOptions)

<StrictMode>
<PostHogProvider client={posthog}>

And got a similar error in the console. Client was already loaded elsewhere, this could cause problems. This is on the latest 1.227.0 version, so not sure why it was closed.

cabello avatar Mar 04 '25 18:03 cabello

Still having this issue.

    "posthog-js": "^1.229.5",
    "react": "^19.0.0",
    "react-router": "^7.1.5",
createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <PostHogProvider
      apiKey={import.meta.env.VITE_PUBLIC_POSTHOG_KEY}
      options={{
        api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST,
      }}
    >
      <BrowserRouter>
  
      </BrowserRouter>
    </PostHogProvider>
  </StrictMode>,
);

In production build:

Image

GustavoMelloGit avatar Mar 09 '25 20:03 GustavoMelloGit

We just ejected from Gatsby and moved to rr7 library mode BrowserRouter, then to DataRouter from createBrowserRouter. Issue still appeared with both, and unlike Gatsby now we have no SSR at all (using createBrowserRouter via custom framework mode with no SSR), so I'm even more sure that it was not created twice. Still using StrictMode, and using latest posthog package as of last week. On one hand doesn't seem like this error actually causes any problems, other hand definitely doesn't seem like it should be showing up at all

olliejm avatar Mar 09 '25 20:03 olliejm

I'm seeing this issue as well, we're using NextJS, just wrapping our component tree in our root layout.tsx file, with the following Provider:

'use client';

import { usePathname, useSearchParams } from 'next/navigation';
import posthog from 'posthog-js';
import { PostHogProvider, usePostHog } from 'posthog-js/react';
import { Suspense, useEffect } from 'react';

if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_POSTHOG_KEY) {
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
    api_host: '/ingest',
    capture_pageleave: true,
    capture_pageview: false, // Disable automatic pageview capture, as we capture manually
    person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
    ui_host: 'https://eu.posthog.com',
  });
}

export function CSPostHogProvider({ children }) {
  return (
    <PostHogProvider client={posthog}>
      <SuspendedPostHogPageView />
      {children}
    </PostHogProvider>
  );
}

// Wrap this in Suspense to avoid the `useSearchParams` usage above
// from de-opting the whole app into client-side rendering
// See: https://nextjs.org/docs/messages/deopted-into-client-rendering
export default function SuspendedPostHogPageView() {
  return (
    <Suspense fallback={null}>
      <PostHogPageView />
    </Suspense>
  );
}

function PostHogPageView() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const posthog = usePostHog();

  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;
}

Floriferous avatar Mar 17 '25 11:03 Floriferous

Update: Just updated posthog-js from 1.210 to 1.231 and the warning disappeared 👍

Floriferous avatar Mar 17 '25 11:03 Floriferous

I am using posthog-js: 1.231.3 and I have this issue in Vite React project.

AndrejGajdos avatar Mar 20 '25 07:03 AndrejGajdos