# Phase 30: Site Tag Detection Registry Expansion

**Status:** Session 2 complete (commit in progress)
**Effort:** 6 hours across 3 sessions (3h + 2h + 1h)
**Risk:** Medium. Touches Site Tag JavaScript running on every client site.

> Full spec content lives in Claude conversation dated May 22-25, 2026.
> This file is a structured summary derived from that conversation.

---

## Problem Statement

The meSEO Site Tag detected approximately 20 plugins across two categories
(booking widgets and chat widgets). A modern WordPress or CMS site typically
has 15-30 trackable integrations. Coverage was roughly 25% of what is
actually present on a typical brand site.

Confirmed via production data on May 22, 2026:
- modernheartandvascular.com (cardiology): 4 plugins detected out of ~15-25 present
- lifeimagingfla.com (imaging): 1 plugin detected out of ~8-15 present

After Phase 30 Session 1: cardiology brand shows 11 detected plugins.

---

## Goal

1. Site Tag detects 50-80 known plugins, widgets, pixels, and integrations
2. Each detection fires a `plugin_detected` event with consistent metadata
   including `category`, `tag_v`, and `confidence`
3. Integrations tab on Site Tag Analytics shows comprehensive per-brand inventories
4. Adding new detection patterns is a small registry edit

---

## Architecture

Detection happens entirely in `public/t.js` (served from Next.js static directory).
The unminified source lives at `public/t.source.js` (gitignored).

**Edit workflow:**
```bash
cp public/t.source.js public/t.js   # copy source to served file
# edit public/t.js
npm run build:site-tag               # minifies in place, backs up to t.source.js
```

**Three registries in `public/t.source.js`:**

| Registry | Location | Category | Count | Event shape |
|---|---|---|---|---|
| `BOOKING_PLUGINS` | ~line 5832 | booking, forms, crm | 15 entries | `{plugin, plugin_key, category, tag_v, confidence}` |
| `CHAT_WIDGETS` | ~line 6416 | chat | 15 entries | `{plugin, plugin_key: "chat_"+key, category: "chat", tag_v, confidence}` |
| `ANALYTICS_PLUGINS` | ~line 6659 | analytics, pixel, seo, page_builder, ecommerce, crm, reviews, cache, security, booking, lead_gen | ~47 entries after Session 2 | `{plugin, plugin_key, category, tag_v, confidence}` |

**Event metadata shape (all registries after Phase 30 Session 1 fix):**
```js
sendEvent('plugin_detected', {
  plugin: 'Google Analytics 4',   // display name
  plugin_key: 'ga4',              // machine key
  category: 'analytics',          // category string
  tag_v: '2026.05.31',            // Site Tag version (bump on each deploy)
  confidence: 'high' | 'medium',  // detection confidence
});
```

---

## Existing Registries (do NOT modify these in Phase 30)

### BOOKING_PLUGINS keys
amelia, calendly, nexhealth, acuity, jotform, typeform, wpforms,
gravityforms, contactform7, hubspot, deardoc, birdeye, podium, weave

### CHAT_WIDGETS keys
intercom, drift, tidio, tawkto, livechat, crisp, olark, hubspot_chat,
zendesk, fb_messenger, smartsupp, jivochat, purechat, userlike, frontchat

---

## ANALYTICS_PLUGINS Entries

### Session 1 (20 entries, commit cdb096f)

**Analytics and pixels (12):**
ga4, gtm, ua_legacy, fb_pixel, linkedin_insight, tiktok_pixel,
twitter_pixel, pinterest_tag, reddit_pixel, clarity, hotjar, amplitude

**SEO (3):** wordpress, yoast, rankmath

**Page builders (1):** elementor

**E-commerce (1):** woocommerce

**CRM (3):** hubspot_track, klaviyo, mailchimp

### Session 2 (~27 additional entries)

**Forms (2):** formidable, fluent_forms

**Page builders (4):** divi, beaver_builder, brizy, bricks

**Booking (4):** bookly, bookingpress, simplybook, setmore

**Reviews (3):** trustpilot, google_reviews_widget, nicejob

**Cache (2):** wp_rocket, litespeed_cache

**Security (2):** wordfence, sucuri

**Healthcare-specific (2):** patientpop, doctible

**SEO (2):** aioseo, seopress

**E-commerce (2):** shopify, edd

**CRM (2):** activecampaign, convertkit

**Skipped (already covered):**
- mailchimp: already in ANALYTICS_PLUGINS
- olark: already in CHAT_WIDGETS (fires as "chat_olark")
- zendesk_chat: already in CHAT_WIDGETS (fires as "chat_zendesk")
- hs_conversations: already in CHAT_WIDGETS (fires as "chat_hubspot_chat")

---

## Detection Strategies

### Window global
```js
detect: () => typeof window.fbq === 'function'
```

### Script src match (uses cached getScriptSrcs())
```js
detect: () => /googletagmanager\.com\/gtm\.js/.test(getScriptSrcs())
```

### DOM selector
```js
detect: () => !!document.querySelector('.gform_wrapper')
```

### Meta tag
```js
detect: () => {
  const meta = document.querySelector('meta[name="generator"]');
  return !!(meta && /Yoast SEO/.test(meta.getAttribute('content') || ''));
}
```

### Cookie name (uses cached getCookies())
```js
detect: () => /_fbp=/.test(getCookies())
```

### Composite (high confidence)
```js
detect: () => {
  const hasGlobal = typeof window.fbq === 'function';
  const hasCookie = /_fbp=/.test(getCookies());
  if (hasGlobal && hasCookie) return { matched: true, confidence: 'high' };
  if (hasGlobal || hasCookie) return { matched: true, confidence: 'medium' };
  return false;
}
```

---

## Performance Constraints

- Detection total work: target under 5ms on mid-range mobile
- `requestIdleCallback` for post-DOMContentLoaded run (5000ms fallback)
- Skip detection if `document.hidden` is true
- `getScriptSrcs()` iterates `document.scripts` once per detection pass (cached)
- `getCookies()` reads `document.cookie` once per detection pass (cached)
- `window.__meseoDetectedKeys` Set prevents any plugin_key firing more than once per page load
- Detection runs at most twice: DOMContentLoaded + requestIdleCallback(timeout: 5000)

---

## Backend: ENRICHMENT_REGISTRY

Location: `src/lib/site-tag/integration-signatures.ts`

Provides vendor info, descriptions, and category defaults for backfill.
Keyed by `plugin_key`. Consulted by:
1. `backfill-detected-integrations` route when resolving category/vendor
2. `site-tag-analytics/integrations` GET route when merging description into response

---

## Phase Sessions

| Session | Status | Commit | Description |
|---|---|---|---|
| Session 1 | Complete | cdb096f | 20 ANALYTICS_PLUGINS rules, BOOKING_PLUGINS category fix, tag_v + confidence fields |
| Session 2 | Complete | (current) | ~27 additional rules, backend enrichment, docs |
| Session 3 | Pending | - | UI polish, category icons, vendor logos |

---

## Acceptance Criteria

- Site Tag detects at least 8 distinct plugins on modernheartandvascular.com (was 4)
- Site Tag detects at least 5 distinct plugins on an active lawn care brand site
- No false positives on a clean test site
- All `plugin_detected` events include `category`, `tag_v`, and `confidence`
- Detection adds less than 10ms to page load p95
- Integrations tab shows expanded set per brand within 24 hours of deploy

---

## Dependencies

- Phase 28A Session 1.5 (backend backfill fix): SHIPPED at commit 058272e
- Phase 28A Session 1.6 (SQL aggregation backfill): SHIPPED at commit 30363ed
- Phase 28A Session 2 (real-time write hook to /api/site-tag/event): PENDING
