If your site adds tags only through Google Tag Manager, install TraceLead as a Custom HTML tag. It does the same as the script tag: it defines the tracelead() queue and loads the snippet asynchronously. Nothing is stored or sent until consent is signalled, exactly as with the script tag.
Status: tested on every release by injecting the tag after the page has loaded, the way GTM fires it, then signalling consent and submitting a form (tests/e2e/gtm.spec.ts). See the integrations ledger.
1. Add the tag
On your site's page in TraceLead, open Install the snippet, switch step 1 to Google Tag Manager and copy the code; it already contains your site's public ID. In GTM:
- Tags → New → Tag Configuration → Custom HTML, paste the code.
- Triggering: choose All Pages (or Initialization - All Pages to load it as early as possible).
- Save, preview with Tag Assistant, then Submit and publish the container.
The code looks like this, with your snippet URL and site ID filled in:
<!-- TraceLead snippet 1.x: queue stub and async loader (docs: /docs/gtm) -->
<script>
window.tracelead = window.tracelead || function () { (window.tracelead.q = window.tracelead.q || []).push(arguments); };
(function () {
if (document.querySelector('script[data-tracelead-loader]')) { return; }
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.tracelead.io/snippet/v1/tracelead.js';
script.setAttribute('data-site', 'tl_YOUR_SITE_ID');
script.setAttribute('data-tracelead-loader', 'gtm');
document.head.appendChild(script);
})();
</script>
The tag loads the snippet once per page even if it fires twice (for example on a history-change trigger).
Or import the container
Download the container export and import it under Admin → Import Container, choosing Merge and Rename conflicting tags. It adds the tag, an all-pages trigger and a constant variable TraceLead site ID; set that variable to your site's public ID before publishing.
2. Signal consent
The tag only loads the snippet. Consent is still signalled with tracelead('consent', true) (and false on withdrawal), from one of:
- Your consent banner's own callback, as in Consent integration. Because the tag defines the queue, a call made before the snippet has arrived is kept and applied when it does.
- A second Custom HTML tag containing
<script>window.tracelead('consent', true);</script>, fired by your consent manager's GTM trigger for the marketing category. With Google Consent Mode, open the tag's Advanced Settings → Consent Settings, choose Require additional consent for tag to fire and addad_storage; fire it on All Pages and on your CMP's consent-update event.
Leave TraceLead's consent mode on Explicit in the site settings. Do not mark the loader tag itself as needing consent unless you also want the dashboard to miss visitors who consent later on the same page: the loader stores nothing by itself.
3. Add hidden fields
Unchanged from the script-tag install: add hidden inputs named tl_<field> (or carrying data-tracelead) to the forms you care about. See Installing the snippet.
Content Security Policy
A Custom HTML tag runs inline script injected by GTM, so a site with a strict CSP already allows GTM's inline execution (usually with a nonce passed to GTM). The snippet itself needs the two allowances in Content Security Policy: the snippet's origin in script-src and the TraceLead API in connect-src.
Checking it
Open the page with ?utm_source=test&utm_medium=cpc, accept the banner and run tracelead('diagnostics', console.log) in the console: the version, consent: true and the mappings' match counts show the tag works. In GTM's preview, the tag should fire once per page.