{"id":9319,"date":"2026-08-09T15:37:30","date_gmt":"2026-08-09T13:37:30","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/werkzeuge\/gtm-container-history-deep-search-engine\/"},"modified":"2026-08-28T16:14:56","modified_gmt":"2026-08-28T14:14:56","slug":"gtm-container-history-deep-search-engine","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/","title":{"rendered":"GTM-Containerverlauf und Tiefensuche"},"content":{"rendered":"<p><script src=\"https:\/\/accounts.google.com\/gsi\/client\" async defer><\/script><\/p>\n<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<div class=\"lw-aussenhinweis\" style=\"background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid #fbbf24; border-radius: 6px; padding: 14px 16px; margin-bottom: 20px;\">\n<div style=\"color: #fbbf24; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 6px;\">Ben\u00f6tigt eine Google-Anmeldung<\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin: 0 0 8px; font-size: 0.9rem; line-height: 1.55;\">Anders als die \u00fcbrigen Werkzeuge hier arbeitet dieses nicht f\u00fcr sich allein. Es liest aus der Google Tag Manager REST API v2 und verlangt daf\u00fcr eine Anmeldung bei Google. Das angeforderte Recht lautet tagmanager.readonly und ist ausschlie\u00dflich lesend \u2014 \u00e4ndern l\u00e4sst sich dar\u00fcber nichts.<\/p>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin: 0; font-size: 0.9rem; line-height: 1.55;\">Was geholt wird, bleibt in dieser Registerkarte: Die Auswertung l\u00e4uft im Browser, an lukaswojcik.com geht nichts. Die unten vorbelegte OAuth-Client-ID l\u00e4sst sich durch eine eigene ersetzen.<\/p>\n<\/div>\n<p style=\"color: var(--text-secondary); margin-bottom: 20px; line-height: 1.6;\">\n        Verbindet sich per OAuth 2.0 direkt mit der <strong>Google Tag Manager REST API v2<\/strong>.<br \/>\n        Ruft die Versions-Header ab und durchsucht Hunderte von Containerversionen nach Tags, Skripten, Triggern oder Variablen &#8211; ganz ohne manuellen Dateiexport.\n    <\/p>\n<p>    <!-- STEP 1: OAUTH & API AUTHENTICATION --><\/p>\n<div style=\"background: var(--bg-body, #101416); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 20px;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">1. Authentifizierung an der Google API<\/h3>\n<div style=\"display: flex; gap: 15px; flex-wrap: wrap; align-items: flex-end;\">\n<div style=\"flex: 1; min-width: 280px;\">\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Google Cloud OAuth Client ID:<\/label><br \/>\n                <input type=\"text\" id=\"api-client-id\" value=\"423029313598-2ko0jilc28eevp253rqncvodg2181e1l.apps.googleusercontent.com\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-primary); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <button id=\"auth-btn\" class=\"button\" style=\"background: var(--accent); color: var(--on-accent); border: none; padding: 11px 22px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Mit Google autorisieren<\/button>\n            <\/div>\n<\/p><\/div>\n<div data-mp-mask id=\"auth-status\" style=\"margin-top: 10px; font-size: 0.85rem; color: var(--text-secondary);\">Status: <strong style=\"color: #ff6b6b;\">Nicht verbunden<\/strong><\/div>\n<\/p><\/div>\n<p>    <!-- STEP 2: CONTAINER SELECTOR --><\/p>\n<div id=\"container-selector-panel\" style=\"background: var(--bg-body); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 20px; display: none;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">2. GTM-Container und Versionsbereich w\u00e4hlen<\/h3>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 15px;\">\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">GTM-Konto:<\/label><br \/>\n                <select data-mp-mask id=\"account-select\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\"><option value=\"\">&#8212; Konto w\u00e4hlen &#8212;<\/option><\/select>\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Container:<\/label><br \/>\n                <select data-mp-mask id=\"container-select\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\" disabled><option value=\"\">&#8212; Container w\u00e4hlen &#8212;<\/option><\/select>\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Zu pr\u00fcfender Versionsbereich:<\/label><br \/>\n                <select id=\"range-select\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\" disabled><option value=\"30\">Letzte 30 Versionen (schnell)<\/option><option value=\"100\">Letzte 100 Versionen<\/option><option value=\"300\">Letzte 300 Versionen<\/option><option value=\"all\">ALLE Versionen (vollst\u00e4ndige Pr\u00fcfung)<\/option><\/select>\n            <\/div>\n<\/p><\/div>\n<div data-mp-mask id=\"header-status\" style=\"font-size: 0.85rem; color: var(--text-secondary);\"><\/div>\n<\/p><\/div>\n<p>    <!-- STEP 3: DEEP SEARCH CONTROLS --><\/p>\n<div id=\"search-controls-panel\" style=\"background: var(--bg-body); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 25px; display: none;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">3. Tiefensuche im Versionsverlauf<\/h3>\n<div style=\"display: flex; gap: 15px; flex-wrap: wrap; margin-bottom: 15px;\">\n<div style=\"flex: 1; min-width: 260px;\">\n                <input type=\"text\" id=\"search-query\" placeholder=\"z. B. G-XXXXXXX, fbq(, analytics_storage oder ^gtm\\..*\" style=\"width: 100%; padding: 12px; background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-primary); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <button id=\"run-api-search-btn\" class=\"button\" style=\"background: var(--accent); color: var(--on-accent); border: none; padding: 12px 28px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Tiefensuche \u00fcber die API starten<\/button>\n            <\/div>\n<\/p><\/div>\n<div style=\"display: flex; gap: 15px; flex-wrap: wrap; align-items: center; border-top: 1px solid var(--border); padding-top: 15px; font-size: 0.85rem;\">\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" id=\"opt-regex\"> Regul\u00e4ren Ausdruck verwenden<\/label><br \/>\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" id=\"opt-case\"> Gro\u00df-\/Kleinschreibung beachten<\/label><br \/>\n            <span style=\"color: var(--border);\">|<\/span><br \/>\n            <span style=\"color: var(--text-primary); font-weight: bold;\">Suchbereiche:<\/span><br \/>\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" class=\"scope-cb\" value=\"tag\" checked> Tags<\/label><br \/>\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" class=\"scope-cb\" value=\"trigger\" checked> Trigger<\/label><br \/>\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" class=\"scope-cb\" value=\"variable\" checked> Variablen<\/label><br \/>\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" class=\"scope-cb\" value=\"customTemplate\" checked> Vorlagen<\/label><br \/>\n            <label style=\"color: var(--text-secondary); cursor: pointer;\"><input type=\"checkbox\" class=\"scope-cb\" value=\"folder\" checked> Ordner<\/label>\n        <\/div>\n<p>        <!-- PROGRESS BAR --><\/p>\n<div id=\"progress-container\" style=\"margin-top: 15px; display: none;\">\n<div style=\"display: flex; justify-content: space-between; font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 5px;\">\n                <span data-mp-mask id=\"progress-text\">GTM-API-Versionen werden gepr\u00fcft &#8230;<\/span><br \/>\n                <span data-mp-mask id=\"progress-percent\">0%<\/span>\n            <\/div>\n<div style=\"width: 100%; height: 8px; background: #242b30; border-radius: 4px; overflow: hidden;\">\n<div id=\"progress-bar\" style=\"width: 0%; height: 100%; background: #51cf66; transition: width 0.2s;\"><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>    <!-- RESULTS --><\/p>\n<div data-mp-mask id=\"api-search-results\"><\/div>\n<\/div>\n<p><script>\n(() => {\n    let accessToken = null;\n    let tokenClient = null;\n    let versionHeaders = [];\n    const accountsMap = {};\n    const containersMap = {};<\/p>\n<p>    const authBtn = document.getElementById(\"auth-btn\");\n    const authStatus = document.getElementById(\"auth-status\");\n    const accSelect = document.getElementById(\"account-select\");\n    const contSelect = document.getElementById(\"container-select\");\n    const rangeSelect = document.getElementById(\"range-select\");\n    const headerStatus = document.getElementById(\"header-status\");\n    const resultsEl = document.getElementById(\"api-search-results\");\n    const progressCont = document.getElementById(\"progress-container\");\n    const progressBar = document.getElementById(\"progress-bar\");\n    const progressText = document.getElementById(\"progress-text\");\n    const progressPercent = document.getElementById(\"progress-percent\");<\/p>\n<p>    const esc = (str) => String(str).replace(\/&\/g, \"&amp;\").replace(\/<\/g, \"&lt;\").replace(\/>\/g, \"&gt;\");<\/p>\n<p>    \/\/ 1. OAUTH 2.0 INITIALIZATION\n    authBtn.addEventListener(\"click\", () => {\n        const clientId = document.getElementById(\"api-client-id\").value.trim();\n        if (!clientId) {\n            alert(\"Bitte eine g\u00fcltige Google Cloud Client ID eingeben.\");\n            return;\n        }<\/p>\n<p>        if (!window.google || !google.accounts || !google.accounts.oauth2) {\n            alert(\"Das Skript von Google Identity Services wird noch geladen. Bitte in einem Moment erneut versuchen.\");\n            return;\n        }<\/p>\n<p>        tokenClient = google.accounts.oauth2.initTokenClient({\n            client_id: clientId,\n            scope: \"https:\/\/www.googleapis.com\/auth\/tagmanager.readonly\",\n            callback: (resp) => {\n                if (resp.error) {\n                    authStatus.innerHTML = \"Status: <strong style='color:#ff6b6b;'>Authentifizierungsfehler: \" + esc(resp.error) + \"<\/strong>\";\n                    return;\n                }\n                accessToken = resp.access_token;\n                authStatus.innerHTML = \"Status: <strong style='color:#51cf66;'>Verbunden (nur Lesezugriff)<\/strong>\";\n                document.getElementById(\"container-selector-panel\").style.display = \"block\";\n                loadAccounts();\n            }\n        });\n        tokenClient.requestAccessToken();\n    });<\/p>\n<p>    \/\/ 2. API FETCHER WITH RATE-LIMIT THROTTLING & ADVANCED ERROR DECODING\n    const gtmApi = async (path) => {\n        const res = await fetch(\"https:\/\/tagmanager.googleapis.com\/tagmanager\/v2\/\" + path, {\n            headers: { \"Authorization\": \"Bearer \" + accessToken }\n        });\n        if (res.status === 429) {\n            await new Promise(r => setTimeout(r, 1500));\n            return gtmApi(path);\n        }\n        if (!res.ok) {\n            let errDetails = res.statusText || \"Unbekannter API-Fehler\";\n            try {\n                const errJson = await res.json();\n                if (errJson && errJson.error && errJson.error.message) {\n                    errDetails = errJson.error.message;\n                }\n            } catch (e) {}\n            throw new Error(\"API-Fehler \" + res.status + \": \" + errDetails);\n        }\n        return res.json();\n    };<\/p>\n<p>    const loadAccounts = async () => {\n        try {\n            accSelect.innerHTML = \"<option>Konten werden geladen ...<\/option>\";\n            const data = await gtmApi(\"accounts\");\n            accSelect.innerHTML = \"<option value='>-- Konto w\u00e4hlen --<\/option>\";\n            (data.account || []).forEach(a => {\n                accountsMap[a.accountId] = a.name;\n                const opt = document.createElement(\"option\");\n                opt.value = a.accountId;\n                opt.textContent = a.name + \" (\" + a.accountId + \")\";\n                accSelect.appendChild(opt);\n            });\n        } catch (e) {\n            accSelect.innerHTML = \"<option>Fehler beim Laden der Konten<\/option>\";\n            alert(\"Konten konnten nicht abgerufen werden: \" + e.message);\n        }\n    };<\/p>\n<p>    accSelect.addEventListener(\"change\", async () => {\n        const accId = accSelect.value;\n        if (!accId) return;\n        try {\n            contSelect.innerHTML = \"<option>Container werden geladen ...<\/option>\";\n            contSelect.disabled = true;\n            const data = await gtmApi(\"accounts\/\" + accId + \"\/containers\");\n            contSelect.innerHTML = \"<option value='>-- Container w\u00e4hlen --<\/option>\";\n            (data.container || []).forEach(c => {\n                containersMap[c.containerId] = c;\n                const opt = document.createElement(\"option\");\n                opt.value = c.containerId;\n                opt.textContent = c.name + \" (\" + c.publicId + \")\";\n                contSelect.appendChild(opt);\n            });\n            contSelect.disabled = false;\n        } catch (e) {\n            alert(\"Container konnten nicht geladen werden: \" + e.message);\n        }\n    });<\/p>\n<p>    contSelect.addEventListener(\"change\", async () => {\n        const accId = accSelect.value;\n        const contId = contSelect.value;\n        if (!contId) return;\n        try {\n            headerStatus.innerHTML = \"Metadaten aller Containerversionen werden abgerufen ...\";\n            const data = await gtmApi(\"accounts\/\" + accId + \"\/containers\/\" + contId + \"\/version_headers\");\n            versionHeaders = (data.containerVersionHeader || []).sort((a, b) => Number(b.containerVersionId) - Number(a.containerVersionId));\n            headerStatus.innerHTML = \"<strong style='color:#51cf66;'>Erfolg:<\/strong> In diesem Container wurden <strong>\" + versionHeaders.length + \" Versionen<\/strong> gefunden.\";\n            rangeSelect.disabled = false;\n            document.getElementById(\"search-controls-panel\").style.display = \"block\";\n        } catch (e) {\n            headerStatus.innerHTML = \"<span style='color:#ff6b6b;'>Fehler beim Laden der Versions-Header: \" + esc(e.message) + \"<\/span>\";\n        }\n    });<\/p>\n<p>    \/\/ 3. DEEP SEARCH TRAVERSAL LOGIC\n    const searchInObject = (obj, regex, path = \"\") => {\n        const matches = [];\n        if (typeof obj === \"string\") {\n            if (regex.test(obj)) matches.push({ path: path || \"value\", snippet: obj });\n        } else if (Array.isArray(obj)) {\n            obj.forEach((item, idx) => matches.push(...searchInObject(item, regex, path ? path + \"[\" + idx + \"]\" : \"[\" + idx + \"]\")));\n        } else if (obj && typeof obj === \"object\") {\n            for (const key in obj) {\n                if (Object.prototype.hasOwnProperty.call(obj, key)) {\n                    const val = obj[key];\n                    const nextPath = path ? path + \".\" + key : key;\n                    if (regex.test(key)) matches.push({ path: nextPath, snippet: typeof val === \"object\" ? JSON.stringify(val) : String(val) });\n                    matches.push(...searchInObject(val, regex, nextPath));\n                }\n            }\n        }\n        return matches;\n    };<\/p>\n<p>    const getBadge = (type) => {\n        const colors = {\n            tag: { bg: \"#1a3a4b\", color: \"#51cf66\", label: \"TAG\" },\n            trigger: { bg: \"#4b3a1a\", color: \"#ff922b\", label: \"TRIGGER\" },\n            variable: { bg: \"#2a1a4b\", color: \"#339af0\", label: \"VARIABLE\" },\n            customTemplate: { bg: \"#4b1a47\", color: \"#cc5de8\", label: \"VORLAGE\" },\n            folder: { bg: \"#242b30\", color: \"#a0a6b0\", label: \"ORDNER\" }\n        };\n        const c = colors[type] || { bg: \"#242b30\", color: \"#ffffff\", label: type.toUpperCase() };\n        return \"<span style='background:\" + c.bg + \"; color:\" + c.color + \"; padding:3px 8px; border-radius:4px; font-size:0.75rem; font-weight:700;'>\" + c.label + \"<\/span>\";\n    };<\/p>\n<p>    \/\/ 4. QUEUED SCANNER ENGINE\n    document.getElementById(\"run-api-search-btn\").addEventListener(\"click\", async () => {\n        const query = document.getElementById(\"search-query\").value.trim();\n        if (!query) { alert(\"Bitte einen Suchbegriff eingeben.\"); return; }<\/p>\n<p>        const isRegex = document.getElementById(\"opt-regex\").checked;\n        const isCase = document.getElementById(\"opt-case\").checked;\n        const activeScopes = Array.from(document.querySelectorAll(\".scope-cb:checked\")).map(cb => cb.value);<\/p>\n<p>        let regex;\n        try {\n            const flags = isCase ? \"g\" : \"gi\";\n            regex = isRegex ? new RegExp(query, flags) : new RegExp(query.replace(\/[.*+?^${}()|[\\]\\\\]\/g, \"\\\\$&\"), flags);\n        } catch (e) {\n            alert(\"Ung\u00fcltiger regul\u00e4rer Ausdruck: \" + e.message); return;\n        }<\/p>\n<p>        const rangeVal = rangeSelect.value;\n        const toScan = rangeVal === \"all\" ? versionHeaders : versionHeaders.slice(0, Number(rangeVal));<\/p>\n<p>        resultsEl.innerHTML = \"\";\n        progressCont.style.display = \"block\";\n        const allResults = [];\n        let completed = 0;<\/p>\n<p>        \/\/ Run batch pool of 3 concurrent API calls to avoid 429 limit\n        const concurrency = 3;\n        for (let i = 0; i < toScan.length; i += concurrency) {\n            const batch = toScan.slice(i, i + concurrency);\n            await Promise.all(batch.map(async (vh) => {\n                try {\n                    const fullVer = await gtmApi(vh.path);\n                    activeScopes.forEach((scope) => {\n                        const items = fullVer[scope] || [];\n                        items.forEach((item) => {\n                            const itemMatches = searchInObject(item, regex);\n                            if (itemMatches.length > 0) {\n                                allResults.push({\n                                    versionId: vh.containerVersionId,\n                                    versionName: vh.name || \"(ohne Namen)\",\n                                    type: scope,\n                                    entityName: item.name || \"(unbenanntes Element)\",\n                                    matches: itemMatches\n                                });\n                            }\n                        });\n                    });\n                } catch (err) {\n                    console.error(\"Error scanning version \" + vh.containerVersionId, err);\n                } finally {\n                    completed++;\n                    const pct = Math.round((completed \/ toScan.length) * 100);\n                    progressBar.style.width = pct + \"%\";\n                    progressPercent.textContent = pct + \"%\";\n                    progressText.textContent = \"Version \" + completed + \" von \" + toScan.length + \" gepr\u00fcft ...\";\n                }\n            }));\n        }<\/p>\n<p>        progressText.textContent = \"Pr\u00fcfung abgeschlossen!\";<\/p>\n<p>        if (!allResults.length) {\n            resultsEl.innerHTML = \"<\/p>\n<div style='background:var(--bg-body); padding:25px; border-radius:6px; border:1px solid var(--border); text-align:center; color:var(--text-secondary);'>Keine Treffer f\u00fcr <strong>\" + esc(query) + \"<\/strong> in den gepr\u00fcften Versionen.<\/div>\n<p>\";\n            return;\n        }<\/p>\n<p>        allResults.sort((a, b) => Number(b.versionId) - Number(a.versionId));<\/p>\n<p>        const cardsHtml = allResults.map((res) => {\n            const matchRows = res.matches.slice(0, 6).map((m) => [\n                \"<\/p>\n<div style='background:#0b1114; border:1px solid var(--border); padding:10px; border-radius:4px; margin-top:8px; font-family:monospace; font-size:0.85rem; overflow-x:auto;'>\",\n                \"  <span style='color:#ff922b; display:block; margin-bottom:4px;'>\" + esc(m.path) + \"<\/span>\",\n                \"  <span style='color:#e0e6ed; white-space:pre-wrap;'>\" + esc(m.snippet.slice(0, 400)) + (m.snippet.length > 400 ? \"...\" : \"\") + \"<\/span>\",\n                \"<\/div>\n<p>\"\n            ].join(\"\")).join(\"\");<\/p>\n<p>            return [\n                \"<\/p>\n<div style='background:var(--bg-body); border:1px solid var(--border); border-radius:8px; padding:18px; margin-bottom:15px;'>\",\n                \"  <\/p>\n<div style='display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px; border-bottom:1px solid var(--border); padding-bottom:12px; margin-bottom:12px;'>\",\n                \"    <\/p>\n<div style='display:flex; align-items:center; gap:10px;'>\",\n                \"      \" + getBadge(res.type),\n                \"      <strong style='color:var(--text-primary); font-size:1.05rem;'>\" + esc(res.entityName) + \"<\/strong>\",\n                \"    <\/div>\n<p>\",\n                \"    <\/p>\n<div style='color:var(--text-secondary); font-size:0.85rem;'>\",\n                \"      Gefunden in Version: <strong style='color:var(--accent);'>v\" + esc(res.versionId) + \"<\/strong> (\" + esc(res.versionName) + \")\",\n                \"    <\/div>\n<p>\",\n                \"  <\/p><\/div>\n<p>\",\n                \"  <\/p>\n<div style='color:var(--text-secondary); font-size:0.85rem;'>\u00dcbereinstimmende Eigenschaften (\" + res.matches.length + \"):<\/div>\n<p>\",\n                \"  \" + matchRows,\n                \"<\/p><\/div>\n<p>\"\n            ].join(\"\");\n        }).join(\"\");<\/p>\n<p>        resultsEl.innerHTML = [\n            \"<\/p>\n<h3 style='color:var(--text-primary); margin-bottom:15px; font-size:1.15rem;'>Treffer im Versionsverlauf: \" + allResults.length + \"<\/h3>\n<p>\",\n            cardsHtml\n        ].join(\"\");\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Durchsucht \u00fcber die Google-Tag-Manager-API s\u00e4mtliche Containerversionen nach Tags, Triggern, Variablen, Vorlagen und Ordnern, ganz ohne manuellen Dateiexport.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":9283,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[92145],"class_list":["post-9319","page","type-page","status-publish","hentry","tag-google-tag-manager-de"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GTM-Containerverlauf und Tiefensuche - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GTM-Containerverlauf und Tiefensuche - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Durchsucht \u00fcber die Google-Tag-Manager-API s\u00e4mtliche Containerversionen nach Tags, Triggern, Variablen, Vorlagen und Ordnern, ganz ohne manuellen Dateiexport.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-28T14:14:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/gtm-container-history-deep-search-engine\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/gtm-container-history-deep-search-engine\\\/\",\"name\":\"GTM-Containerverlauf und Tiefensuche - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-09T13:37:30+00:00\",\"dateModified\":\"2026-08-28T14:14:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/gtm-container-history-deep-search-engine\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/gtm-container-history-deep-search-engine\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/gtm-container-history-deep-search-engine\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/toolbox-2\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GTM-Containerverlauf und Tiefensuche\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"GTM-Containerverlauf und Tiefensuche - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/","og_locale":"en_US","og_type":"article","og_title":"GTM-Containerverlauf und Tiefensuche - Lukas Wojcik - Blog","og_description":"Durchsucht \u00fcber die Google-Tag-Manager-API s\u00e4mtliche Containerversionen nach Tags, Triggern, Variablen, Vorlagen und Ordnern, ganz ohne manuellen Dateiexport.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-08-28T14:14:56+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/","name":"GTM-Containerverlauf und Tiefensuche - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-09T13:37:30+00:00","dateModified":"2026-08-28T14:14:56+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/gtm-container-history-deep-search-engine\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/toolbox-2\/"},{"@type":"ListItem","position":3,"name":"GTM-Containerverlauf und Tiefensuche"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=9319"}],"version-history":[{"count":5,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9319\/revisions"}],"predecessor-version":[{"id":13086,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9319\/revisions\/13086"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9283"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=9319"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=9319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}