RFC: Google Tag Manager and gtag in next/third-parties
#53868
Replies: 16 comments 8 replies
-
This is definitely a great resource. I wish it were available for other applications that are non next.js based |
Beta Was this translation helpful? Give feedback.
-
My team would love this – especially anything that can get GTM working in a web worker more easily! |
Beta Was this translation helpful? Give feedback.
-
To what extent would this |
Beta Was this translation helpful? Give feedback.
-
Seeing as |
Beta Was this translation helpful? Give feedback.
-
Should using web worker fallback to non-web worker be a use case? |
Beta Was this translation helpful? Give feedback.
-
That looks like an interesting improvement. Also a I was wondering: how is this coupled to Next.js, couldn't it run in other React apps as well? |
Beta Was this translation helpful? Give feedback.
-
Sounds fantastic! This is a burning issue for my client, we’ve had trouble getting GTM to load in a worker with the docs/advice currently available. Any currently working example would be much appreciated! |
Beta Was this translation helpful? Give feedback.
-
@housseindjirdeh, awesome writeup |
Beta Was this translation helpful? Give feedback.
-
package json: - "next": "13.4.20-canary.15", dont work for me (( can i this way place code ? |
Beta Was this translation helpful? Give feedback.
-
I am in process of doing this in a big NextJS rebuild and would be very helpful. |
Beta Was this translation helpful? Give feedback.
-
Does anyone know of any open codebases where any of this sort of work has been done already? I'm about to add GTM to a site and I know that if I don't use the worker route from the start it'll be much harder to add it later on. |
Beta Was this translation helpful? Give feedback.
-
https://nextjs.org/conf/speakers/houssein-djirdeh Looking forward to this @housseindjirdeh :) |
Beta Was this translation helpful? Give feedback.
-
Also recommend automating pageview event tracking on hook call so users of the package needn't worry about figuring out how to do that. In pages folder, it was easy with the router event listeners. For App Dir, the only solution I've found is listed here: https://stackoverflow.com/a/76760064/7304377 Some people like to customize pageview events though, so maybe allow an opt-out as part of the passed params to the hook? |
Beta Was this translation helpful? Give feedback.
-
Another suggestion: Use the minimal GA implementation that Jake Archibald once shared on Twitter for a small client-side impact for GA4 users. |
Beta Was this translation helpful? Give feedback.
-
Where should the code in script.onload be placed with this plugin |
Beta Was this translation helpful? Give feedback.
-
An important use case the current implementation does not support is Consent Mode. In a nutshell, it prevents GTM from actually collecting data until a user explicitly consents (via a cookie banner or other mechanism). For this to work, similar to @SouthLink 's post above this, we'd need to be able to instantiate the dataLayer with some additional objects. The <script>
window.dataLayer = window.dataLayer ||[];
function gtag(){dataLayer.push(arguments);}
gtag('consent','default',{
'ad_storage':'denied',
'analytics_storage':'denied',
'ad_user_data':'denied',
'ad_personalization':'denied',
'personalization_storage':'denied',
'functionality_storage':'granted',
'security_storage':'granted',
'wait_for_update': 500
});
gtag("set", "ads_data_redaction", true);
</script> Ideally, I'd love to be able to set this like: const gtmDefaultDataLayer = [
[
'consent',
'default',
{
ad_storage: 'denied',
analytics_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
personalization_storage: 'denied',
functionality_storage: 'granted',
security_storage: 'granted',
wait_for_update: 500,
},
],
['set', 'ads_data_redaction', true],
];
//...
<GoogleTagManager gtmId="GTM-XXXXXX" dataLayer={gtmDefaultDataLayer} /> Which would imply that ${dataLayer ? `w[l].push(${JSON.stringify(dataLayer)})` : ''} Whereas instead it should spread into ${dataLayer ? `w[l].push(...${JSON.stringify(dataLayer )})` : ''} |
Beta Was this translation helpful? Give feedback.
-
Goal
Improve the performance and developer experience of loading Google tag (
gtag.js
) and Google Tag Manager in a Next.js application.Background
We recently launched next/third-parties (still experimental and in early development), which provides components and utilities that improve the performance and developer experience of loading popular third-party libraries. In the original RFC discussion, we proposed the inclusion of Google Analytics as a component:
After further consideration, we realized that this may not be the best approach for the following reasons:
gtag.js
in order to include Google Analytics to their page. It can be counterintuitive to provide a GoogleAnalytics export since this can confuse developers if they need to include other Google tag dependencies (e.g. Google Ads)gtag()
command to send data to their products when using Google tag. A component model does not make it easy for developers to understand how to do this at the page/component/layout level.This RFC proposes a different approach to support Google Analytics (via Google tag) as well as Google Tag Manager in next/third-parties using React hooks instead of components.
Proposal
Google tag (
gtag.js
)We suggest providing a
useGoogleTag
hook with aninit
method to initialize a Google tag on a page. Although GTM can also be used to load Google Analytics, this will be the recommended approach in the documentation to include Google Analytics on a page:By default, this will load
gtag
and all subsequent child scripts after the page has finished loading and become interactive (akin to next/script’safterInteractive
strategy).In addition, we can provide a
send
method to send events:We can similarly provide methods for each of the commands (
config
,get
,set
,event
, andconsent
).Google Tag Manager
We suggest a
useGoogleTagManager
hook with an init method to initialize GTM on a page:By default, this will load the GTM container and all subsequent child scripts after the page has finished loading and become interactive (akin to next/script’s afterInteractive strategy).
Web worker support
We can provide developers with the option to opt-in to process their Google tag or GTM container in a web worker (via Partytown) through a different initialization method. Note that this is just an idea and the final API can change:
This feature will also likely be released in a later update.
Why include a web worker mode?
We conducted some initial tests to compare the impact on performance of loading Google Tag Manager with different loading techniques. Overall, offloading to a web worker was, by far, the most effective method.
The graphs below show the results of an experiment that measured the impact of a 22-tag GTM container on the performance of a Next.js application. Seven different loading methods were used to load the same number of GTM tags, while all other variables were kept constant1.
1 See Appendix for experiment details
A while back, we rolled out an experimental worker strategy to the Script component to allow anyone to move the processing of a third-party script to a web worker. This feature, which uses Partytown, is especially useful when used for tag managers but it can be tricky to set up.
There are a number of things that need to be done in order for Partytown to work with tag managers like GTM and
gtag.js
. We can automate and/or simplify this as much as possible for developers who decide to useinitWorker
. This includes:Appendix
Experiment Details:
For each loading method, three different throttling experiments were used.
The accuracy and variance of each throttling mechanism differs. For this experiment, the exact measured values are not as important as the differences observed when switching between scenarios. If you would like to read more details about each type of throttling, please refer to “Network Throttling”.
In this experiment, Total Blocking Time (TBT) is used as a measure to evaluate whether background GTM activity would prevent user interactions and have a negative impact on INP.
Beta Was this translation helpful? Give feedback.
All reactions