diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 4a56a7b524741..c515df8ea467a 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,7 +1,6 @@ { "name": "@next/third-parties", "version": "13.5.6-canary.3", - "private": true, "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" diff --git a/packages/third-parties/src/google/GoogleMapsEmbed.tsx b/packages/third-parties/src/google/google-maps-embed.tsx similarity index 100% rename from packages/third-parties/src/google/GoogleMapsEmbed.tsx rename to packages/third-parties/src/google/google-maps-embed.tsx diff --git a/packages/third-parties/src/google/gtm.tsx b/packages/third-parties/src/google/gtm.tsx new file mode 100644 index 0000000000000..f8e5462784616 --- /dev/null +++ b/packages/third-parties/src/google/gtm.tsx @@ -0,0 +1,68 @@ +'use client' +// TODO: Evaluate import 'client only' +import React from 'react' +import Script from 'next/script' + +declare global { + interface Window { + dataLayer?: Object[] + [key: string]: any + } +} + +type GTMParams = { + gtmId: string + dataLayer: string[] + dataLayerName: string + auth: string + preview: string +} + +let currDataLayerName: string | undefined = undefined + +export function GoogleTagManager(props: GTMParams) { + const { gtmId, dataLayerName = 'dataLayer', auth, preview, dataLayer } = props + + if (currDataLayerName === undefined) { + currDataLayerName = dataLayerName + } + + const gtmLayer = dataLayerName !== 'dataLayer' ? `$l=${dataLayerName}` : '' + const gtmAuth = auth ? `>m_auth=${auth}` : '' + const gtmPreview = preview ? `>m_preview=${preview}>m_cookies_win=x` : '' + + return ( + <> + + + > + ) +} + +export const sendGTMEvent = (data: Object) => { + if (currDataLayerName === undefined) { + console.warn(`@next/third-parties: GTM has not been initialized`) + return + } + + if (window[currDataLayerName]) { + window[currDataLayerName].push(data) + } else { + console.warn( + `@next/third-parties: GTM dataLayer ${currDataLayerName} does not exist` + ) + } +} diff --git a/packages/third-parties/src/google/index.tsx b/packages/third-parties/src/google/index.tsx index aa704aae1c427..e5b94408a56e9 100644 --- a/packages/third-parties/src/google/index.tsx +++ b/packages/third-parties/src/google/index.tsx @@ -1,2 +1,3 @@ -export { default as GoogleMapsEmbed } from './GoogleMapsEmbed' -export { default as YouTubeEmbed } from './YouTubeEmbed' +export { default as GoogleMapsEmbed } from './google-maps-embed' +export { default as YouTubeEmbed } from './youtube-embed' +export { GoogleTagManager, sendGTMEvent } from './gtm' diff --git a/packages/third-parties/src/google/YouTubeEmbed.tsx b/packages/third-parties/src/google/youtube-embed.tsx similarity index 100% rename from packages/third-parties/src/google/YouTubeEmbed.tsx rename to packages/third-parties/src/google/youtube-embed.tsx diff --git a/test/e2e/app-dir/third-parties/app/gtm/page.js b/test/e2e/app-dir/third-parties/app/gtm/page.js new file mode 100644 index 0000000000000..34d56d8508d59 --- /dev/null +++ b/test/e2e/app-dir/third-parties/app/gtm/page.js @@ -0,0 +1,23 @@ +'use client' + +import React from 'react' +import { GoogleTagManager, sendGTMEvent } from '@next/third-parties/google' + +const Page = () => { + const onClick = () => { + sendGTMEvent({ event: 'buttonClicked', value: 'xyz' }) + } + + return ( +