Skip to content
HomeScripts/marketer-debug-hud

On-page debug HUD

Ctrl+Shift+G opens a panel over the page showing the last five dataLayer entries, the UTM and click IDs in the URL, and whether fbq and gtag are defined. Useful when you cannot open GTM preview on a client site.

Try it
Shows a worked example of the output, not a run against your account.
dataLayer
Nothing yet
GTM Custom HTML Tag (JavaScript)
<script>
(function() {
  var hudId = 'goodlabs-debug-hud';
  var SHOW_PIXEL_STATUS = true;
  var SHOW_UTM_PARAMS = true;
  var SHOW_DATALAYER = true;
  
  function getUtms() {
    var params = new URLSearchParams(window.location.search);
    var utms = {};
    ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'gclid', 'fbclid'].forEach(function(k) {
      if (params.get(k)) utms[k] = params.get(k);
    });
    return utms;
  }

  function renderHud() {
    var existing = document.getElementById(hudId);
    if (existing) { existing.remove(); return; }

    var hud = document.createElement('div');
    hud.id = hudId;
    hud.style.cssText = 'position:fixed;bottom:20px;right:20px;width:380px;max-height:480px;background:#111827;color:#f3f4f6;border-radius:12px;box-shadow:0 12px 36px rgba(0,0,0,0.5);font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px;z-index:9999999;border:1px solid rgba(255,255,255,0.15);overflow:hidden;display:flex;flex-direction:column;';

    var utms = getUtms();
    var utmHtml = Object.keys(utms).length 
      ? Object.keys(utms).map(function(k) { return '<div style="color:#60a5fa"><strong>' + k + ':</strong> ' + utms[k] + '</div>'; }).join('')
      : '<div style="color:#9ca3af">No UTM params found in URL</div>';

    var dl = window.dataLayer || [];
    var lastEvents = dl.slice(-5).map(function(e) {
      return '<div style="background:#1f2937;padding:6px 8px;border-radius:6px;margin-bottom:6px;border-left:3px solid #16a34a">' +
        '<span style="color:#34d399;font-weight:bold">' + (e.event || 'dataLayer.push') + '</span>' +
        '<pre style="margin:4px 0 0;font-size:11px;color:#d1d5db;overflow-x:auto">' + JSON.stringify(e, null, 2) + '</pre>' +
      '</div>';
    }).join('');

    var metaStatus = typeof window.fbq === 'function' ? '<span style="color:#34d399">Active ✓</span>' : '<span style="color:#f87171">Not Detected ✗</span>';
    var gtagStatus = typeof window.gtag === 'function' ? '<span style="color:#34d399">Active ✓</span>' : '<span style="color:#f87171">Not Detected ✗</span>';

    hud.innerHTML = 
      '<div style="padding:10px 14px;background:#1e293b;border-bottom:1px solid rgba(255,255,255,0.1);display:flex;justify-content:space-between;align-items:center;">' +
        '<div style="font-weight:600;color:#fff;display:flex;align-items:center;gap:6px;"><span>⚡</span> Goodlabs Debug HUD</div>' +
        '<button id="goodlabs-hud-close" style="background:none;border:none;color:#9ca3af;font-size:16px;cursor:pointer;padding:0 4px;">&times;</button>' +
      '</div>' +
      '<div style="padding:12px;overflow-y:auto;flex:1;">' +
        (SHOW_PIXEL_STATUS ? ('<div style="margin-bottom:12px;">' +
          '<div style="font-size:11px;letter-spacing:0.01em;color:#9ca3af;margin-bottom:4px;">Pixel status</div>' +
          '<div style="display:flex;gap:12px;"><div>Meta Pixel: ' + metaStatus + '</div><div>GA4/gtag: ' + gtagStatus + '</div></div>' +
        '</div>') : '') +
        (SHOW_UTM_PARAMS ? ('<div style="margin-bottom:12px;">' +
          '<div style="font-size:11px;letter-spacing:0.01em;color:#9ca3af;margin-bottom:4px;">Campaign and click IDs in the URL</div>' +
          utmHtml +
        '</div>') : '') +
        (SHOW_DATALAYER ? ('<div>' +
          '<div style="font-size:11px;letter-spacing:0.01em;color:#9ca3af;margin-bottom:4px;">Last dataLayer entries (' + dl.length + ' total)</div>' +
          (lastEvents || '<div style="color:#9ca3af">dataLayer is empty</div>') +
        '</div>') : '') +
      '</div>';

    document.body.appendChild(hud);
    document.getElementById('goodlabs-hud-close').onclick = function() { hud.remove(); };
  }

  document.addEventListener('keydown', function(e) {
    if (e.ctrlKey && e.shiftKey && (e.key === 'G' || e.key === 'g' || e.code === 'KeyG')) {
      e.preventDefault();
      renderHud();
    }
  });

  window.__goodlabs_debug_hud = renderHud;
})();
</script>

How it works

  1. Listens for Ctrl+Shift+G and toggles a fixed panel in the bottom-right corner.
  2. Reads the last five entries already in window.dataLayer and prints them as formatted JSON. It is a snapshot taken when you open the panel, not a live feed — press the shortcut again to refresh it.
  3. Reads utm_source, utm_medium, utm_campaign, utm_content, utm_term, gclid and fbclid off the current URL.
  4. Reports whether window.fbq and window.gtag are defined as functions.
  5. Holds no state and loads nothing: one keydown listener and a div it removes on close.

Step-by-step installation

  1. Create a New Custom HTML Tag in GTM named "cHTML - Goodlabs Debug HUD".
  2. Paste the code snippet above.
  3. Set trigger to "All Pages" (or only on staging/internal test environments via Cookie/IP trigger).
  4. Publish container and press Ctrl+Shift+G on your website to open the telemetry inspector.

Frequently asked questions

Will ordinary site visitors see this HUD?

No, it stays completely invisible unless someone presses the secret key combination Ctrl+Shift+G.

Can I restrict this to internal team members only?

Add an exception trigger in GTM that blocks the tag unless a test cookie or a ?debug=1 parameter is present, so the tag never reaches ordinary visitors.

Need one of these adapted to your account?

We write Google Ads scripts, set up server-side GA4, and build the reporting that answers a specific question.