🐛 fix(analytics): prevent multiple GTM initializations (#4174)

* feat(types): Add global window interface for Google Tag Manager

* refactor(Chat/Footer): Move GTM initialization to useEffect for better lifecycle management

* fix(hooks): add useEffect to initialize TagManager conditionally
This commit is contained in:
Riya Amemiya 2024-09-21 23:30:40 +09:00 committed by GitHub
parent c1c13a69dc
commit 561650d6f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 14 deletions

View file

@ -540,3 +540,9 @@ export type TVectorStore = {
}; };
export type TThread = { id: string; createdAt: string }; export type TThread = { id: string; createdAt: string };
declare global {
interface Window {
google_tag_manager?: unknown;
}
}

View file

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect } from 'react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import TagManager from 'react-gtm-module'; import TagManager from 'react-gtm-module';
import { Constants } from 'librechat-data-provider'; import { Constants } from 'librechat-data-provider';
@ -34,13 +34,6 @@ export default function Footer({ className }: { className?: string }) {
</a> </a>
); );
if (config?.analyticsGtmId != null) {
const tagManagerArgs = {
gtmId: config.analyticsGtmId,
};
TagManager.initialize(tagManagerArgs);
}
const mainContentParts = ( const mainContentParts = (
typeof config?.customFooter === 'string' typeof config?.customFooter === 'string'
? config.customFooter ? config.customFooter
@ -50,6 +43,15 @@ export default function Footer({ className }: { className?: string }) {
localize('com_ui_latest_footer') localize('com_ui_latest_footer')
).split('|'); ).split('|');
useEffect(() => {
if (config?.analyticsGtmId != null && typeof window.google_tag_manager === 'undefined') {
const tagManagerArgs = {
gtmId: config.analyticsGtmId,
};
TagManager.initialize(tagManagerArgs);
}
}, [config?.analyticsGtmId]);
const mainContentRender = mainContentParts.map((text, index) => ( const mainContentRender = mainContentParts.map((text, index) => (
<React.Fragment key={`main-content-part-${index}`}> <React.Fragment key={`main-content-part-${index}`}>
<ReactMarkdown <ReactMarkdown

View file

@ -100,10 +100,12 @@ export default function useAppStartup({
setAvailableTools({ pluginStore, ...mapPlugins(tools) }); setAvailableTools({ pluginStore, ...mapPlugins(tools) });
}, [allPlugins, user, setAvailableTools]); }, [allPlugins, user, setAvailableTools]);
if (startupConfig?.analyticsGtmId) { useEffect(() => {
const tagManagerArgs = { if (startupConfig?.analyticsGtmId != null && typeof window.google_tag_manager === 'undefined') {
gtmId: startupConfig?.analyticsGtmId, const tagManagerArgs = {
}; gtmId: startupConfig.analyticsGtmId,
TagManager.initialize(tagManagerArgs); };
} TagManager.initialize(tagManagerArgs);
}
}, [startupConfig?.analyticsGtmId]);
} }