diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx index 7c290f2b1..068fffc50 100644 --- a/src/components/Footer.jsx +++ b/src/components/Footer.jsx @@ -3,8 +3,9 @@ import PropTypes from 'prop-types'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { - APP_CONFIG_INITIALIZED, ensureConfig, getConfig, subscribe, + APP_PUBSUB_INITIALIZED, APP_CONFIG_INITIALIZED, ensureConfig, getConfig, mergeConfig, subscribe, } from '@edx/frontend-platform'; +import { loadExternalScripts } from '@edx/frontend-platform/initialize'; import { AppContext } from '@edx/frontend-platform/react'; import { hydrateAuthenticatedUser } from '@edx/frontend-platform/auth'; @@ -14,6 +15,7 @@ import FooterLinks from './footer-links/FooterNavLinks'; import FooterSocial from './footer-links/FooterSocialLinks'; import parseEnvSettings from '../utils/parseData'; import ModalToS from './modal-tos'; +import GoogleTagManagerLoader from '../services/gtmLoader'; ensureConfig([ 'LMS_BASE_URL', @@ -21,6 +23,20 @@ ensureConfig([ 'LOGO_POWERED_BY', ], 'Footer component'); +subscribe(APP_PUBSUB_INITIALIZED, () => { + mergeConfig({ + GOOGLE_TAG_MANAGER_ID: process.env.GOOGLE_TAG_MANAGER_ID || '', + GOOGLE_TAG_MANAGER_ENVIRONMENT: process.env.GOOGLE_TAG_MANAGER_ENVIRONMENT || '', + }, 'NauFooter'); +}); + +subscribe(APP_CONFIG_INITIALIZED, async () => { + await hydrateAuthenticatedUser(); + loadExternalScripts([GoogleTagManagerLoader], { + config: getConfig(), + }); +}); + const EVENT_NAMES = { FOOTER_LINK: 'edx.bi.footer.link', }; @@ -164,9 +180,5 @@ SiteFooter.defaultProps = { supportedLanguages: [], }; -subscribe(APP_CONFIG_INITIALIZED, async () => { - await hydrateAuthenticatedUser(); -}); - export default injectIntl(SiteFooter); export { EVENT_NAMES }; diff --git a/src/services/gtmLoader.js b/src/services/gtmLoader.js new file mode 100644 index 000000000..81f390d7b --- /dev/null +++ b/src/services/gtmLoader.js @@ -0,0 +1,62 @@ +/** + * @implements {GoogleTagManagerLoader} + * @memberof module:GoogleTagManager + */ +class GoogleTagManagerLoader { + constructor({ config }) { + this.gtmId = config.GOOGLE_TAG_MANAGER_ID; + + this.gtmArgs = ''; + if (config.GOOGLE_TAG_MANAGER_ENVIRONMENT) { + if (!config.GOOGLE_TAG_MANAGER_ENVIRONMENT.startsWith('&')) { + this.gtmArgs += '&'; + } + this.gtmArgs += config.GOOGLE_TAG_MANAGER_ENVIRONMENT; + } + } + + loadScript() { + if (!this.gtmId) { + return; + } + + global.googleTagManager = global.googleTagManager || []; + const { googleTagManager } = global; + + // If the snippet was invoked do nothing. + if (googleTagManager.invoked) { + return; + } + + // Invoked flag, to make sure the snippet is never invoked twice. + googleTagManager.invoked = true; + + googleTagManager.load = (key, args, options) => { + const scriptSrc = document.createElement('script'); + scriptSrc.type = 'text/javascript'; + scriptSrc.async = true; + scriptSrc.innerHTML = ` + (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': + new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], + j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= + 'https://www.googletagmanager.com/gtm.js?id='+i+dl+'${args}';f.parentNode.insertBefore(j,f); + })(window,document,'script','dataLayer','${key}'); + `; + document.head.insertBefore(scriptSrc, document.head.getElementsByTagName('script')[0]); + + googleTagManager._loadOptions = options; // eslint-disable-line no-underscore-dangle + + const noScriptSrc = document.createElement('noscript'); + + noScriptSrc.innerHTML = ` + + `; + document.body.insertBefore(noScriptSrc, document.body.childNodes[0]); + }; + + // Load GoogleTagManager with your key. + googleTagManager.load(this.gtmId, this.gtmArgs); + } +} + +export default GoogleTagManagerLoader;