Web Infra

Lazy-Load Google Tag Manager After User Intent

Google Tag Manager does not need to be on the critical rendering path. A small loader can wait until the visitor shows intent, then inject the container once.

Use this snippet near the end of <body>. Replace GTM-XXXXXXX with the container ID from Google Tag Manager.

<script>
  (() => {
    const containerId = "GTM-XXXXXXX";
    const events = ["scroll", "mousemove"];
    let loaded = false;

    function loadGtm() {
      if (loaded) return;
      loaded = true;

      events.forEach((eventName) => {
        window.removeEventListener(eventName, loadGtm);
      });

      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        "gtm.start": Date.now(),
        event: "gtm.js"
      });

      const script = document.createElement("script");
      script.async = true;
      script.src = "https://www.googletagmanager.com/gtm.js?id=" + encodeURIComponent(containerId);
      document.head.appendChild(script);
    }

    events.forEach((eventName) => {
      window.addEventListener(eventName, loadGtm, { once: true, passive: true });
    });
  })();
</script>

This keeps GTM out of the initial page load and avoids starting the tag container for visitors who never interact with the page.