diff --git a/packages/use-gtm/src/__tests__/__snapshots__/index.tsx.snap b/packages/use-gtm/src/__tests__/__snapshots__/index.tsx.snap index 41761c890..365ccd35d 100644 --- a/packages/use-gtm/src/__tests__/__snapshots__/index.tsx.snap +++ b/packages/use-gtm/src/__tests__/__snapshots__/index.tsx.snap @@ -72,3 +72,5 @@ Array [ }, ] `; + +exports[`GTM hook Provider should not load when no id is provided 1`] = `""`; diff --git a/packages/use-gtm/src/__tests__/index.tsx b/packages/use-gtm/src/__tests__/index.tsx index 1f9500bc3..6bca970fb 100644 --- a/packages/use-gtm/src/__tests__/index.tsx +++ b/packages/use-gtm/src/__tests__/index.tsx @@ -64,6 +64,14 @@ describe('GTM hook', () => { expect(document.head.innerHTML).toMatchSnapshot() }) + it('Provider should not load when no id is provided', () => { + renderHook(() => useGTM(), { + wrapper: wrapper({}), + }) + + expect(document.head.innerHTML).toMatchSnapshot() + }) + it('Provider should load when id is provided', () => { renderHook(() => useGTM(), { wrapper: wrapper({ diff --git a/packages/use-gtm/src/useGTM.tsx b/packages/use-gtm/src/useGTM.tsx index ef8720978..72c39ff27 100644 --- a/packages/use-gtm/src/useGTM.tsx +++ b/packages/use-gtm/src/useGTM.tsx @@ -31,7 +31,7 @@ export function useGTM(): GTMContextInterface { } export type GTMProviderProps = { - id: string + id?: string environment?: GTMEnvironment children: ReactNode onLoadError?: () => void @@ -45,20 +45,29 @@ function GTMProvider({ onLoadError, events, }: GTMProviderProps) { + const shouldLoad = !!id + useEffect(() => { - const { noScript, script, dataLayerInit } = generateScripts(id, environment) + if (shouldLoad) { + const { noScript, script, dataLayerInit } = generateScripts( + id, + environment, + ) - document.head.insertBefore(dataLayerInit, document.head.childNodes[0]) - document.head.insertBefore(script, document.head.childNodes[1]) - document.body.insertBefore(noScript, document.body.childNodes[0]) + document.head.insertBefore(dataLayerInit, document.head.childNodes[0]) + document.head.insertBefore(script, document.head.childNodes[1]) + document.body.insertBefore(noScript, document.body.childNodes[0]) - if (onLoadError) document.addEventListener(LOAD_ERROR_EVENT, onLoadError) + if (onLoadError) document.addEventListener(LOAD_ERROR_EVENT, onLoadError) - return () => { - if (onLoadError) - document.removeEventListener(LOAD_ERROR_EVENT, onLoadError) + return () => { + if (onLoadError) + document.removeEventListener(LOAD_ERROR_EVENT, onLoadError) + } } - }, [environment, id, onLoadError]) + + return () => {} + }, [environment, id, onLoadError, shouldLoad]) const value = useMemo>(() => { const curiedEvents = Object.entries(events || {}).reduce( diff --git a/packages/use-segment/src/__tests__/index.tsx b/packages/use-segment/src/__tests__/index.tsx index c25e68672..200888f09 100644 --- a/packages/use-segment/src/__tests__/index.tsx +++ b/packages/use-segment/src/__tests__/index.tsx @@ -80,7 +80,62 @@ describe('segment hook', () => { settings: undefined, }), }) - expect(result.current.analytics).not.toBeNull() + expect(result.current.analytics).toBe(undefined) + }) + + it('useSegment should not load when All integrations disabled', () => { + const { result } = renderHook(() => useSegment(), { + wrapper: wrapper({ + events: defaultEvents, + initOptions: { integrations: { All: false } }, + settings: { writeKey: 'sample ' }, + }), + }) + expect(result.current.analytics).toBe(undefined) + }) + + it('useSegment should not load when all of integrations disabled', () => { + const { result } = renderHook(() => useSegment(), { + wrapper: wrapper({ + events: defaultEvents, + initOptions: { + integrations: { + testInteg: false, + testInteg2: false, + testInteg3: false, + }, + }, + settings: { writeKey: 'sample ' }, + }), + }) + expect(result.current.analytics).toBe(undefined) + }) + + it('useSegment should load when at least one integrations enabled', async () => { + const mock = jest + .spyOn(AnalyticsBrowser, 'load') + .mockResolvedValue([{} as Analytics, {} as Context]) + + const { result, waitForNextUpdate } = renderHook( + () => useSegment(), + { + wrapper: wrapper({ + events: defaultEvents, + initOptions: { + integrations: { + testInteg: false, + testInteg2: true, + testInteg3: false, + }, + }, + settings: { writeKey: 'sample ' }, + }), + }, + ) + + await waitForNextUpdate() + expect(mock).toHaveBeenCalledTimes(1) + expect(result.current.analytics).toStrictEqual({}) }) it('Provider should load with key', async () => { diff --git a/packages/use-segment/src/useSegment.tsx b/packages/use-segment/src/useSegment.tsx index 5fe736838..67671eeb6 100644 --- a/packages/use-segment/src/useSegment.tsx +++ b/packages/use-segment/src/useSegment.tsx @@ -63,15 +63,28 @@ function SegmentProvider({ undefined, ) + const shouldLoad = useMemo(() => { + const hasNoIntegrationsSettings = !initOptions?.integrations + const isAllEnabled = !!initOptions?.integrations?.All + const isAnyIntegrationEnabled = Object.values( + initOptions?.integrations ?? {}, + ).reduce((acc, integration) => !!acc || !!integration, false) + + return ( + !!settings?.writeKey && + (hasNoIntegrationsSettings || isAllEnabled || isAnyIntegrationEnabled) + ) + }, [initOptions?.integrations, settings?.writeKey]) + useEffect(() => { - if (settings?.writeKey) { + if (shouldLoad && settings) { AnalyticsBrowser.load(settings, initOptions) .then(([res]) => setAnalytics(res)) .catch((err: Error) => { onError?.(err) }) } - }, [onError, settings, initOptions]) + }, [onError, settings, initOptions, shouldLoad]) const value = useMemo>(() => { const curiedEvents = Object.entries(events).reduce(