From c287ca33408a8dbb2a3b5c879dd41421079a28fe Mon Sep 17 00:00:00 2001 From: Andrew Yim Date: Tue, 17 Mar 2026 21:55:50 +0900 Subject: [PATCH] feat: update GTM skills triad with field-tested improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gtm-audit (60): - Added Mode D rule: check elements for IDs before designing CSS triggers gtm-editor (61): - Added "Tagging Workflow: dataLayer First" section — always suggest dataLayer push code for developers before creating GTM triggers - Added multi-language snippets (JS, React, Vue, PHP) - Added "Trigger Design: IDs First" section — prefer element IDs, ask user to add IDs before falling back to CSS selectors - Added ID naming convention: [section]-[element]-[action] - Added decision tree for trigger selection gtm-validator (62): - Flag CSS-based triggers as fragility risk during QA - Recommend adding IDs instead of finding alternative CSS selectors Based on field testing with ourdigital.org GTM-N9TPJW container. Co-Authored-By: Claude Opus 4.6 (1M context) --- custom-skills/60-gtm-audit/code/SKILL.md | 1 + custom-skills/61-gtm-editor/code/SKILL.md | 108 +++++++++++++++++++ custom-skills/62-gtm-validator/code/SKILL.md | 3 +- 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/custom-skills/60-gtm-audit/code/SKILL.md b/custom-skills/60-gtm-audit/code/SKILL.md index c3ded5a..566f883 100644 --- a/custom-skills/60-gtm-audit/code/SKILL.md +++ b/custom-skills/60-gtm-audit/code/SKILL.md @@ -136,5 +136,6 @@ One GA4 page_view fires to multiple endpoints — this is normal: - Wait for page to fully load before capturing network requests - Use `evaluate_script` to check consent mode before interpreting missing tags - Orphan count may be high due to GA4 multi-endpoint — note this in reports +- **In Mode D (tag design), check elements for `id` attributes** — if missing, recommend adding IDs before designing CSS-based triggers. Suggest naming: `[section]-[element]-[action]` - Hand off tag creation work to `gtm-editor` skill - Hand off QA/validation work to `gtm-validator` skill diff --git a/custom-skills/61-gtm-editor/code/SKILL.md b/custom-skills/61-gtm-editor/code/SKILL.md index 2d89e62..b3fdc27 100644 --- a/custom-skills/61-gtm-editor/code/SKILL.md +++ b/custom-skills/61-gtm-editor/code/SKILL.md @@ -34,6 +34,89 @@ Create, modify, and deploy GTM configurations via API. Generates ES5-compliant C ### Reporting (Notion MCP) - Write implementation plans and tag configurations to Notion +## Tagging Workflow: dataLayer First (MANDATORY) + +**Always push complexity into the dataLayer, not GTM triggers.** + +### Step 1: Design the dataLayer push FIRST + +Before creating any GTM configuration, design the `dataLayer.push()` that the website should implement. Present this to the user as a code snippet matching their tech stack: + +**For vanilla JS / static HTML (ES5):** +```javascript +window.dataLayer = window.dataLayer || []; +window.dataLayer.push({ + 'event': 'generate_lead', + 'lead_type': document.getElementById('requestType').value, + 'form_id': 'contact-form' +}); +``` + +**For React / Next.js / TypeScript:** +```typescript +declare global { interface Window { dataLayer: Record[]; } } + +window.dataLayer = window.dataLayer || []; +window.dataLayer.push({ + event: 'generate_lead', + lead_type: selectedType, + form_id: 'contact-form', +}); +``` + +**For Vue:** +```javascript +window.dataLayer?.push({ + event: 'generate_lead', + lead_type: this.selectedType, + form_id: 'contact-form', +}); +``` + +**For PHP / WordPress:** +```php +add_action('wp_footer', function() { ?> + + "This element doesn't have an ID. Can you add one to the website/app code? + > Suggested: `id="[section]-[element]-[action]"` e.g., `id="hero-btn-consult"`" +4. Only use CSS selectors when the user explicitly confirms they cannot modify the HTML + +**Priority order:** +1. Element ID (`Click ID equals "hero-btn-consult"`) +2. Data attribute (`Click Element matches CSS [data-track="consult"]`) +3. Form ID (`Form ID equals "contact-form"`) +4. CSS selector (last resort — document which selectors are used) + +**Suggested ID naming:** `[section]-[element]-[action]` +- Navigation: `nav-about`, `nav-services`, `nav-insights` +- CTAs: `hero-btn-consult`, `cta-btn-booking` +- Forms: `contact-form`, `newsletter-form` +- Footer: `footer-social-linkedin`, `footer-email` + ## Rules - Always use `dtm_status` first to verify auth and active container - Always use `measurementIdOverride` for GA4 event tags (NOT `measurementId`) +- **Always prefer element IDs for triggers — ask user to add IDs before using CSS selectors** - All Custom HTML must be ES5-compatible - Use `--dry-run` conceptually — verify trigger selectors via Chrome DevTools before creating - Rate limit: space API calls 1 second apart in batch operations diff --git a/custom-skills/62-gtm-validator/code/SKILL.md b/custom-skills/62-gtm-validator/code/SKILL.md index e653af2..29e84a1 100644 --- a/custom-skills/62-gtm-validator/code/SKILL.md +++ b/custom-skills/62-gtm-validator/code/SKILL.md @@ -220,5 +220,6 @@ Compare tags between two container versions to identify changes. - Test on both desktop and mobile viewports when possible - Check consent mode state before flagging missing tags - Document every test result with screenshots or network request evidence -- If a trigger selector doesn't match, suggest a fix and hand off to gtm-editor +- **When a trigger uses CSS selectors instead of IDs, flag it as a fragility risk** — recommend adding `id` attributes to the HTML +- If a trigger selector doesn't match, suggest adding an ID to the element first (not a different CSS selector) and hand off to gtm-editor - GTM questions, best practices, and architecture advice are also in scope