Skip to content

Commit

Permalink
feat: Enhance PostHogProvider to prevent double initialization
Browse files Browse the repository at this point in the history
Added state management to track if the PostHog client has already been initialized, addressing issues that arise when running under React.StrictMode. This change includes warnings for users if the client is loaded multiple times, improving the overall robustness of the PostHogProvider component.

Closes #723
  • Loading branch information
rafaeelaudibert committed Jan 22, 2025
1 parent 9067391 commit 1dd6f66
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion react/src/context/PostHogProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable no-console */
import posthogJs, { PostHogConfig } from 'posthog-js'

import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'
import { PostHog, PostHogContext } from './PostHogContext'

type WithOptionalChildren<T> = T & { children?: React.ReactNode | undefined }
Expand All @@ -28,6 +28,10 @@ type PostHogProviderProps =
* but not both simultaneously.
*/
export function PostHogProvider({ children, client, apiKey, options }: WithOptionalChildren<PostHogProviderProps>) {
// Used to detect if the client was already initialized
// This is used to prevent double initialization when running under React.StrictMode
const [alreadyInitialized, setAlreadyInitialized] = useState(false)

const posthog = useMemo(() => {
if (client) {
if (apiKey) {
Expand All @@ -50,11 +54,27 @@ export function PostHogProvider({ children, client, apiKey, options }: WithOptio
}

if (apiKey) {
// If the client was already initialized, return the existing instance
// This is likely to occur when someone is developing locally under `React.StrictMode`
//
// There's no built-in way to detect React.StrictMode, so we set a flag to check if the client was already initialized
// and return the existing instance if it was.
if (alreadyInitialized) {
return posthogJs
}

// If it's the first time running this, but it has been loaded elsewhere, warn the user about it.
if (posthogJs.__loaded) {
console.warn('[PostHog.js] `posthog` was already loaded elsewhere. This may cause issues.')
}

// Init global client
posthogJs.init(apiKey, options)

// Keep track of whether the client was already initialized
// This is used to prevent double initialization when running under React.StrictMode
setAlreadyInitialized(true)

return posthogJs
}

Expand Down

0 comments on commit 1dd6f66

Please sign in to comment.