{"id":29,"date":"2026-07-03T13:36:45","date_gmt":"2026-07-03T11:36:45","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?page_id=29"},"modified":"2026-07-03T14:20:48","modified_gmt":"2026-07-03T12:20:48","slug":"gtm-duplicates-analyser","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/","title":{"rendered":"GTM Duplicates Analyser"},"content":{"rendered":"<div class=\"gtm-analyser-container\">\n<p style=\"color: var(--text-secondary); margin-bottom: 20px; line-height: 1.6;\">\n        Paste your Google Tag Manager JSON export below to instantly find redundant variables and triggers.<br \/>\n        The script analyzes the raw configuration logic, ignoring names and IDs, to accurately detect exact duplicates. Nothing you enter here is saved or stored on my servers.\n    <\/p>\n<p>    <textarea id=\"gtm-input\" placeholder=\"Paste your GTM container JSON here...\"><\/textarea><br \/>\n    <button id=\"analyze-btn\" class=\"button\">Run Analysis<\/button><\/p>\n<div id=\"error-message\" style=\"color: #ff6b6b; margin-top: 15px; font-weight: bold;\"><\/div>\n<div id=\"results\" class=\"results-section\" style=\"margin-top: 30px;\"><\/div>\n<\/div>\n<style>\n    \/* Scoped styles to match your dark theme and blue accents *\/\n    .gtm-analyser-container textarea {\n        width: 100%;\n        height: 250px;\n        padding: 15px;\n        background-color: var(--bg-panel, #1e1e24);\n        border: 1px solid var(--border, #2a2a35);\n        border-radius: 8px;\n        color: var(--text-primary, #e0e0e0);\n        font-family: 'Consolas', 'Courier New', monospace;\n        font-size: 0.9rem;\n        box-sizing: border-box;\n        resize: vertical;\n        transition: border-color 0.3s ease;\n    }<\/p>\n<p>    .gtm-analyser-container textarea:focus {\n        outline: none;\n        border-color: var(--accent, #2ba6df);\n    }<\/p>\n<p>    .gtm-analyser-container .button {\n        display: inline-block;\n        margin-top: 15px;\n        background-color: transparent;\n        color: var(--accent, #2ba6df);\n        border: 1px solid var(--accent, #2ba6df);\n        padding: 10px 24px;\n        cursor: pointer;\n        border-radius: 6px;\n        font-weight: 700;\n        font-size: 0.95rem;\n        transition: all 0.2s ease;\n    }<\/p>\n<p>    .gtm-analyser-container .button:hover {\n        background-color: var(--accent, #2ba6df);\n        color: #ffffff;\n    }<\/p>\n<p>    .duplicate-card {\n        background: var(--bg-panel, #1e1e24);\n        border-left: 4px solid var(--accent, #2ba6df);\n        padding: 15px;\n        margin-bottom: 12px;\n        border-radius: 4px;\n        color: var(--text-secondary, #a0a0a0);\n        font-size: 0.95rem;\n        box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n    }<\/p>\n<p>    .duplicate-card strong {\n        color: var(--text-primary, #e0e0e0);\n    }\n<\/style>\n<p><script>\n    class GTMDuplicatesFinder {\n        constructor(jsn_JSON) {\n            \/\/ Validate the JSON structure based on the original source logic[cite: 2]\n            if (!jsn_JSON || !jsn_JSON.containerVersion) {\n                throw new Error('Invalid GTM JSON format. Please ensure you pasted a valid container export.');\n            }\n            this.triggers = jsn_JSON.containerVersion.trigger || [];\n            this.variables = jsn_JSON.containerVersion.variable || [];\n        }<\/p>\n<p>        findDuplicates() {\n            const duplicateVariables = [];\n            const duplicateTriggers = [];<\/p>\n<p>            \/\/ Helper function to compare raw logic (ignoring IDs and names)[cite: 2]\n            const getLogicHash = (obj, fields) => {\n                const cleanObj = {};\n                fields.forEach(f => { \n                    if (obj[f] !== undefined) cleanObj[f] = obj[f]; \n                });\n                return JSON.stringify(cleanObj);\n            };<\/p>\n<p>            \/\/ 1. Analyze Duplicate Variables[cite: 2]\n            const varHashes = {};\n            const varFields = ['type', 'parameter', 'formatValue'];<\/p>\n<p>            this.variables.forEach(v => {\n                const hash = getLogicHash(v, varFields);\n                if (varHashes[hash]) {\n                    duplicateVariables.push({ name1: varHashes[hash], name2: v.name });\n                } else {\n                    varHashes[hash] = v.name;\n                }\n            });<\/p>\n<p>            \/\/ 2. Analyze Duplicate Triggers[cite: 2]\n            const trgHashes = {};\n            const trgFields = [\n                'type', 'filter', 'autoEventFilter', 'customEventFilter', \n                'parameter', 'waitForTags', 'waitForTagsTimeout', \n                'checkValidation', 'interval', 'uniqueTriggerId',\n                'eventName', 'limit'\n            ];<\/p>\n<p>            this.triggers.forEach(t => {\n                const hash = getLogicHash(t, trgFields);\n                if (trgHashes[hash]) {\n                    duplicateTriggers.push({ name1: trgHashes[hash], name2: t.name });\n                } else {\n                    trgHashes[hash] = t.name;\n                }\n            });<\/p>\n<p>            return { variables: duplicateVariables, triggers: duplicateTriggers };\n        }\n    }<\/p>\n<p>    \/\/ UI Interaction Handler\n    document.getElementById('analyze-btn').addEventListener('click', () => {\n        const inputField = document.getElementById('gtm-input').value;\n        const errorDiv = document.getElementById('error-message');\n        const resultsDiv = document.getElementById('results');<\/p>\n<p>        \/\/ Reset states\n        errorDiv.innerText = '';\n        resultsDiv.innerHTML = '';<\/p>\n<p>        if (!inputField.trim()) {\n            errorDiv.innerText = 'Please paste the JSON code first.';\n            return;\n        }<\/p>\n<p>        try {\n            const parsedJSON = JSON.parse(inputField);\n            const analyzer = new GTMDuplicatesFinder(parsedJSON);\n            const duplicates = analyzer.findDuplicates();<\/p>\n<p>            let html = `<\/p>\n<h3 style=\"color: var(--text-primary); margin-bottom: 25px; border-bottom: 1px solid var(--border); padding-bottom: 10px;\">Analysis Results<\/h3>\n<p>`;<\/p>\n<p>            \/\/ Render Variables\n            html += `<\/p>\n<h4 style=\"color: var(--accent); margin-bottom: 15px; font-size: 1.1rem;\">Duplicate Variables (${duplicates.variables.length})<\/h4>\n<p>`;\n            if (duplicates.variables.length === 0) {\n                html += '<\/p>\n<p style=\"color: var(--text-secondary); margin-bottom: 25px;\">\u2705 No duplicate variables found.<\/p>\n<p>';\n            } else {\n                duplicates.variables.forEach(d => {\n                    html += `<\/p>\n<div class=\"duplicate-card\">\n                                <strong>${d.name2}<\/strong> is an exact logic copy of <strong>${d.name1}<\/strong>\n                             <\/div>\n<p>`;\n                });\n                html += '<\/p>\n<div style=\"margin-bottom: 25px;\"><\/div>\n<p>';\n            }<\/p>\n<p>            \/\/ Render Triggers\n            html += `<\/p>\n<h4 style=\"color: var(--accent); margin-bottom: 15px; font-size: 1.1rem;\">Duplicate Triggers (${duplicates.triggers.length})<\/h4>\n<p>`;\n            if (duplicates.triggers.length === 0) {\n                html += '<\/p>\n<p style=\"color: var(--text-secondary);\">\u2705 No duplicate triggers found.<\/p>\n<p>';\n            } else {\n                duplicates.triggers.forEach(d => {\n                    html += `<\/p>\n<div class=\"duplicate-card\">\n                                <strong>${d.name2}<\/strong> is an exact logic copy of <strong>${d.name1}<\/strong>\n                             <\/div>\n<p>`;\n                });\n            }<\/p>\n<p>            resultsDiv.innerHTML = html;<\/p>\n<p>        } catch (e) {\n            errorDiv.innerText = 'Processing Error: ' + e.message;\n        }\n    });\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Paste your Google Tag Manager JSON export below to instantly find redundant variables and triggers. The script analyzes the raw configuration logic, ignoring names and IDs, to accurately detect exact duplicates. Nothing you enter here is saved or stored on my servers. Run Analysis<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"class_list":["post-29","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GTM Duplicates Analyser - 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\/en\/toolbox\/gtm-duplicates-analyser\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GTM Duplicates Analyser - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Paste your Google Tag Manager JSON export below to instantly find redundant variables and triggers. The script analyzes the raw configuration logic, ignoring names and IDs, to accurately detect exact duplicates. Nothing you enter here is saved or stored on my servers. Run Analysis\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-03T12:20:48+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/gtm-duplicates-analyser\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/gtm-duplicates-analyser\\\/\",\"name\":\"GTM Duplicates Analyser - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-07-03T11:36:45+00:00\",\"dateModified\":\"2026-07-03T12:20:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/gtm-duplicates-analyser\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/gtm-duplicates-analyser\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/gtm-duplicates-analyser\\\/#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\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GTM Duplicates Analyser\"}]},{\"@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\":\"luky\",\"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\":\"luky\"},\"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 Duplicates Analyser - 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\/en\/toolbox\/gtm-duplicates-analyser\/","og_locale":"en_US","og_type":"article","og_title":"GTM Duplicates Analyser - Lukas Wojcik - Blog","og_description":"Paste your Google Tag Manager JSON export below to instantly find redundant variables and triggers. The script analyzes the raw configuration logic, ignoring names and IDs, to accurately detect exact duplicates. Nothing you enter here is saved or stored on my servers. Run Analysis","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-07-03T12:20:48+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/","name":"GTM Duplicates Analyser - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-07-03T11:36:45+00:00","dateModified":"2026-07-03T12:20:48+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/gtm-duplicates-analyser\/#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\/"},{"@type":"ListItem","position":3,"name":"GTM Duplicates Analyser"}]},{"@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":"luky","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":"luky"},"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\/29","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=29"}],"version-history":[{"count":7,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/29\/revisions"}],"predecessor-version":[{"id":40,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/29\/revisions\/40"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=29"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}