@ssheleg/sheleg-dev 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/LICENSE +21 -0
  3. package/README.md +132 -0
  4. package/SECURITY.md +63 -0
  5. package/bin/sheleg-dev.js +99 -0
  6. package/package.json +45 -0
  7. package/plugins/sheleg-dev/.claude-plugin/plugin.json +28 -0
  8. package/plugins/sheleg-dev/skills/ad-tracking/SKILL.md +442 -0
  9. package/plugins/sheleg-dev/skills/ad-tracking/references/consent-mode.md +257 -0
  10. package/plugins/sheleg-dev/skills/ad-tracking/references/event-tracking.md +201 -0
  11. package/plugins/sheleg-dev/skills/ad-tracking/references/gtag-api.md +389 -0
  12. package/plugins/sheleg-dev/skills/ad-tracking/references/meta-linkedin.md +103 -0
  13. package/plugins/sheleg-dev/skills/ad-tracking/references/performance-security.md +288 -0
  14. package/plugins/sheleg-dev/skills/crypto-payments/SKILL.md +384 -0
  15. package/plugins/sheleg-dev/skills/crypto-payments/references/heleket-provider.md +1357 -0
  16. package/plugins/sheleg-dev/skills/frontend-performance/SKILL.md +147 -0
  17. package/plugins/sheleg-dev/skills/frontend-performance/references/accessibility-perf.md +172 -0
  18. package/plugins/sheleg-dev/skills/frontend-performance/references/css-performance.md +180 -0
  19. package/plugins/sheleg-dev/skills/frontend-performance/references/nextjs.md +271 -0
  20. package/plugins/sheleg-dev/skills/google-auth/SKILL.md +275 -0
  21. package/plugins/sheleg-dev/skills/google-auth/references/adc-and-service-accounts.md +464 -0
  22. package/plugins/sheleg-dev/skills/google-auth/references/oauth2-web-server.md +615 -0
  23. package/plugins/sheleg-dev/skills/google-auth/references/sign-in-with-google.md +593 -0
  24. package/plugins/sheleg-dev/skills/google-auth/references/workload-identity.md +376 -0
  25. package/plugins/sheleg-dev/skills/google-signin/SKILL.md +121 -0
  26. package/plugins/sheleg-dev/skills/google-signin/references/full-guide.md +421 -0
  27. package/plugins/sheleg-dev/skills/stripe-billing/SKILL.md +458 -0
  28. package/plugins/sheleg-dev/skills/stripe-billing/references/price-integrity.md +201 -0
  29. package/plugins/sheleg-dev/skills/stripe-billing/references/stripe-agent-toolchain.md +173 -0
  30. package/plugins/sheleg-dev/skills/stripe-billing/references/subscription-lifecycle.md +294 -0
  31. package/plugins/sheleg-dev/skills/stripe-billing/references/testing-and-local-dev.md +214 -0
  32. package/plugins/sheleg-dev/skills/stripe-billing/references/webhook-events.md +211 -0
@@ -0,0 +1,442 @@
1
+ ---
2
+ name: ad-tracking
3
+ description: >-
4
+ Use when setting up or modifying ad pixel integration, conversion tracking, consent
5
+ management, purchase event tracking, retargeting audiences, or auditing an existing
6
+ advertising analytics stack. Covers Google Analytics 4, Google Ads, Meta (Facebook) Pixel and
7
+ LinkedIn Insight Tag in web applications: Consent Mode v2, standard events, e-commerce
8
+ tracking, advanced matching, Enhanced Conversions, CSP configuration, user identification,
9
+ cross-device tracking, and GDPR/DMA compliance. Triggers - "ad tracking", "conversion
10
+ tracking", "meta pixel", "fbq", "google ads", "GA4", "gtag", "consent mode", "cookie consent",
11
+ "enhanced conversions", "retargeting", "purchase event", "CAPI", "gclid", "UTM",
12
+ "attribution", "отслеживание конверсий", "пиксель Meta", "согласие на куки", "ретаргетинг",
13
+ "аналитика рекламы". Not for running the ad campaigns themselves.
14
+ ---
15
+
16
+ # Advertising Analytics & Conversion Tracking Integration
17
+
18
+ Complete reference for integrating Google Analytics 4, Google Ads, Meta (Facebook) Pixel, and LinkedIn Insight Tag into web applications with proper consent management, standard event mapping, user identification, and GDPR/DMA compliance.
19
+
20
+ ---
21
+
22
+ ## What this skill covers
23
+
24
+ GA4, Google Ads, Meta Pixel and LinkedIn Insight Tag, all behind Consent Mode
25
+ v2. The body carries the minimal setup and the traps; the tables, schemas and
26
+ per-framework wiring live in `references/`, listed at the bottom.
27
+ ## Architecture Overview
28
+
29
+ A modern advertising analytics stack consists of multiple pixels/tags that must all respect the same consent state. The architecture follows this pattern:
30
+
31
+ ```
32
+ ┌──────────────────────────────────────────────────────────┐
33
+ │ CONSENT LAYER │
34
+ │ Cookie Consent Banner → localStorage → consent state │
35
+ │ All pixels gated by the same consent storage key │
36
+ └────────────────────┬─────────────────────────────────────┘
37
+ │ granted / denied
38
+ ┌───────────────┼──────────────────┬──────────────────┐
39
+ ▼ ▼ ▼ ▼
40
+ ┌─────────┐ ┌────────────┐ ┌──────────────┐ ┌────────────┐
41
+ │ GA4 + │ │ Meta │ │ LinkedIn │ │ Mixpanel │
42
+ │ Google │ │ Pixel │ │ Insight │ │ (product │
43
+ │ Ads │ │ (fbq) │ │ Tag │ │ analytics)│
44
+ └─────────┘ └────────────┘ └──────────────┘ └────────────┘
45
+ │ │ │ │
46
+ ▼ ▼ ▼ ▼
47
+ Consent Consent-gated Consent-gated Consent-gated
48
+ Mode v2 (render only (render only (opt_in /
49
+ (built-in) when granted) when granted) opt_out)
50
+ ```
51
+
52
+ **Key principle:** GA4 uses its own built-in Consent Mode v2 (defaults denied, updates on consent). All other pixels (Meta, LinkedIn, Mixpanel) use a consent-gated pattern — they are not rendered at all until the user grants consent. A shared `CustomEvent` allows dynamic consent changes without page reload.
53
+
54
+ ---
55
+
56
+ ## Consent
57
+
58
+ Read `references/consent-mode.md` for all seven consent signals, Advanced vs
59
+ Basic mode, region-specific defaults, granular consent and GTM wiring. Consent
60
+ Mode v2 is **mandatory** in the EU/EEA since March 2024.
61
+
62
+ **The order is the whole thing, and getting it wrong is invisible:**
63
+
64
+ ```
65
+ 1. dataLayer init + gtag() stub
66
+ 2. gtag('consent', 'default', { …'denied', wait_for_update: 500 })
67
+ 3. restore a stored decision → gtag('consent', 'update', …)
68
+ 4. load gtag.js (async)
69
+ 5. gtag('js', new Date()) + gtag('config', TAG_ID)
70
+ ```
71
+
72
+ Steps 1–3 must run **synchronously before** gtag.js loads. A page that sets
73
+ defaults after the script has loaded looks correct in every test that begins by
74
+ accepting consent, and loses the denied population entirely.
75
+
76
+ **Denied is not off.** With Advanced mode Google still receives cookieless
77
+ pings and models conversions from them — roughly two thirds of the otherwise
78
+ lost data. Blocking the script instead throws that away.
79
+ ## Google Analytics 4
80
+
81
+ ### Setup
82
+
83
+ **Env var:** `NEXT_PUBLIC_GA_MEASUREMENT_ID` (format: `G-XXXXXXXXXX`)
84
+
85
+ **Script loading:**
86
+
87
+ ```html
88
+ <!-- 1. Consent defaults (MUST be first) -->
89
+ <script>
90
+ window.dataLayer = window.dataLayer || [];
91
+ function gtag(){dataLayer.push(arguments);}
92
+ gtag('consent', 'default', {
93
+ ad_storage: 'denied', ad_user_data: 'denied',
94
+ ad_personalization: 'denied', analytics_storage: 'denied',
95
+ wait_for_update: 500
96
+ });
97
+ // Restore prior consent
98
+ try {
99
+ if (localStorage.getItem('consent_key') === 'granted') {
100
+ gtag('consent', 'update', {
101
+ ad_storage: 'granted', ad_user_data: 'granted',
102
+ ad_personalization: 'granted', analytics_storage: 'granted'
103
+ });
104
+ }
105
+ } catch(e) {}
106
+ </script>
107
+
108
+ <!-- 2. Load gtag.js -->
109
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
110
+
111
+ <!-- 3. Configure -->
112
+ <script>
113
+ gtag('js', new Date());
114
+ gtag('config', 'G-XXXXXXXXXX', { allow_enhanced_conversions: true });
115
+ </script>
116
+ ```
117
+
118
+ ### Commands and events
119
+
120
+ Read `references/gtag-api.md` → **Commands** for `config` / `event` / `set` /
121
+ `get` / `consent` with parameter scope and precedence, and
122
+ `references/event-tracking.md` → **Recommended Events** for the GA4 names
123
+ Google Ads can import (`sign_up`, `login`, `begin_checkout`, `purchase`,
124
+ `generate_lead`, `view_item`) with their required parameters.
125
+
126
+ **SPA page views are not automatic when you send them yourself.** Enhanced
127
+ measurement fires `page_view` on History API changes; adding a manual one on
128
+ route change double-counts every navigation. Send manual page views only for
129
+ hash routing.
130
+ ### SPA Page Tracking
131
+
132
+ GA4 with enhanced measurement automatically tracks `page_view` via the History API for Single Page Applications. Manual `page_view` tracking is only needed for hash routing (`#/path`). Consent state persists across SPA route changes.
133
+
134
+ **Docs:**
135
+ - [Set up the Google tag](https://developers.google.com/tag-platform/gtagjs)
136
+ - [gtag.js API reference](https://developers.google.com/tag-platform/gtagjs/reference)
137
+ - [Recommended events](https://developers.google.com/tag-platform/gtagjs/reference/events)
138
+ - [Event parameters](https://developers.google.com/tag-platform/gtagjs/reference/parameters)
139
+ - [Data routing & groups](https://developers.google.com/tag-platform/gtagjs/routing)
140
+
141
+ ---
142
+
143
+ ## Google Ads Conversion Tracking
144
+
145
+ ### Architecture
146
+
147
+ GA4 and Google Ads share the same gtag.js snippet. When `NEXT_PUBLIC_GOOGLE_ADS_ID` (format: `AW-XXXXXXXXX`) is set, add a second `config` call:
148
+
149
+ ```javascript
150
+ gtag('config', 'G-XXXXXXXXXX'); // GA4
151
+ gtag('config', 'AW-XXXXXXXXX'); // Google Ads
152
+ ```
153
+
154
+ Both share consent state, first-party cookies, and the dataLayer pipeline.
155
+
156
+ ### Enhanced Conversions
157
+
158
+ Enhanced Conversions improve attribution by matching hashed user data (email, phone) with Google accounts. Setup:
159
+
160
+ 1. Enable in GA4 config: `allow_enhanced_conversions: true`
161
+ 2. Set user data before conversion events fire:
162
+
163
+ ```javascript
164
+ gtag('set', 'user_data', {
165
+ email: 'user@example.com', // Google hashes automatically
166
+ phone_number: '+1234567890', // optional
167
+ });
168
+ ```
169
+
170
+ 3. Enable in Google Ads console: Tools → Conversions → Enhanced conversions → Turn on
171
+
172
+ ### user_id (Cross-Device Tracking)
173
+
174
+ Set GA4 `user_id` after authentication to enable cross-device tracking and audience building:
175
+
176
+ ```javascript
177
+ gtag('config', 'G-XXXXXXXXXX', {
178
+ user_id: 'USER_123',
179
+ send_page_view: false // prevent duplicate page_view
180
+ });
181
+ ```
182
+
183
+ ### gclid Preservation Through External Redirects
184
+
185
+ The `gclid` from Google Ads auto-tagging is stored in the `_gcl_aw` first-party cookie. This cookie persists across external redirects (e.g. Stripe Checkout → return URL) because it's set on your domain. No additional code needed.
186
+
187
+ ### Google Ads console setup
188
+
189
+ Read `references/gtag-api.md` → **Multi-Product Configuration** for wiring one
190
+ gtag loader to both GA4 and Ads. In the Ads console the conversion action must
191
+ be **Primary** and its attribution window set before the first click lands, or
192
+ early conversions are attributed under the old settings and cannot be
193
+ recomputed.
194
+ ## Meta (Facebook) Pixel
195
+
196
+ ### Setup
197
+
198
+ **Env var:** `NEXT_PUBLIC_META_PIXEL_ID` (numeric string)
199
+
200
+ **Base code (consent-gated):**
201
+
202
+ ```javascript
203
+ !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
204
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
205
+ n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
206
+ t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
207
+ (window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
208
+ fbq('init', 'PIXEL_ID');
209
+ fbq('track', 'PageView');
210
+ ```
211
+
212
+ **noscript fallback (required for pixel verification):**
213
+
214
+ ```html
215
+ <noscript>
216
+ <img height="1" width="1" style="display:none"
217
+ src="https://www.facebook.com/tr?id=PIXEL_ID&ev=PageView&noscript=1"/>
218
+ </noscript>
219
+ ```
220
+
221
+ ### Standard Events
222
+
223
+ Meta defines 17 standard events. The most important for SaaS conversion funnels:
224
+
225
+ | Event | When | Parameters | Notes |
226
+ |---|---|---|---|
227
+ | `PageView` | Every page load | (automatic from base code) | Fires from the init script |
228
+ | `CompleteRegistration` | User signs up | `content_name` (method), `status: true` | Separate from GA4 `sign_up` |
229
+ | `InitiateCheckout` | Checkout started | `value`, `currency`, `content_name`, `content_category`, `num_items` | |
230
+ | `Purchase` | Purchase completed | `value` (required), `currency` (required), `content_name`, `content_category`, `content_type`, `contents[]` | `value` + `currency` are **mandatory** for optimisation |
231
+ | `Subscribe` | Recurring subscription | `value`, `currency`, `predicted_ltv` | Distinct from one-time Purchase |
232
+ | `Lead` | Lead form submitted | (optional params) | |
233
+ | `ViewContent` | Key content viewed | `content_name`, `content_category` | |
234
+ | `AddToCart` | Item added to cart | `content_name`, `value`, `currency` | |
235
+ | `Search` | Search performed | `search_string` | |
236
+
237
+ ### Deeper Meta and LinkedIn detail
238
+
239
+ Read `references/meta-linkedin.md` for the parameter object per event, the
240
+ firing wrapper, advanced matching (hashed identifiers, and what must never be
241
+ sent) and CAPI deduplication.
242
+ ## LinkedIn Insight Tag
243
+
244
+ ### Setup
245
+
246
+ **Env var:** `NEXT_PUBLIC_LINKEDIN_PARTNER_ID` (numeric string)
247
+
248
+ The LinkedIn Insight Tag is consent-gated (same pattern as Meta Pixel). It loads the `insight.min.js` script and includes a noscript pixel fallback.
249
+
250
+ ```javascript
251
+ _linkedin_partner_id = "PARTNER_ID";
252
+ window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
253
+ window._linkedin_data_partner_ids.push(_linkedin_partner_id);
254
+ ```
255
+
256
+ ### Conversion Tracking
257
+
258
+ LinkedIn conversions are configured in Campaign Manager (not in code). The Insight Tag automatically tracks page views, and you define URL-based conversion rules in the LinkedIn Campaign Manager:
259
+
260
+ 1. Campaign Manager → Analyze → Conversion tracking → Create conversion
261
+ 2. Define URL rules (e.g. `/thank-you`, `/onboarding`)
262
+ 3. LinkedIn Insight Tag automatically matches page loads to conversion rules
263
+
264
+ For event-based conversions, use `window.lintrk('track', { conversion_id: 123456 })`.
265
+
266
+ **Docs:**
267
+ - [LinkedIn Insight Tag setup](https://www.linkedin.com/help/lms/answer/a418880)
268
+ - [LinkedIn conversion tracking](https://www.linkedin.com/help/lms/answer/a423304)
269
+
270
+ ---
271
+
272
+ ## User Identification
273
+
274
+ ### Cross-Platform Identification Strategy
275
+
276
+ | Platform | Method | When | What it enables |
277
+ |---|---|---|---|
278
+ | GA4 | `user_id` via `gtag('config', TAG_ID, { user_id })` | After login/onboarding | Cross-device tracking, audience building |
279
+ | GA4 | Enhanced Conversions via `gtag('set', 'user_data', { email })` | After login/onboarding | Better conversion attribution |
280
+ | Meta Pixel | Advanced Matching via `fbq('init', PIXEL_ID, { em, fn })` | After login/onboarding | Better conversion attribution, larger custom audiences |
281
+ | Mixpanel | `alias()` + `identify()` | After login/onboarding | Merge anonymous → identified user profiles |
282
+
283
+ **All identification calls should be placed in a single identification component** that runs in the dashboard/authenticated layout. This ensures:
284
+ - User data is sent once per session
285
+ - All platforms receive identification data at the same time
286
+ - Pre-login anonymous events merge into the identified profile
287
+
288
+ ### Alias vs Identify (Mixpanel)
289
+
290
+ - `alias(userId, anonymousId)` — creates a permanent link between the anonymous and real user ID. Must be called **exactly once** per user, **before** `identify()`. Use a localStorage flag to prevent duplicate calls.
291
+ - `identify(userId)` — sets the user ID for all subsequent events.
292
+
293
+ ### Timing
294
+
295
+ Fire identification in a `useEffect` in the authenticated layout:
296
+
297
+ ```typescript
298
+ useEffect(() => {
299
+ // 1. Mixpanel alias + identify
300
+ // 2. GA4 user_id + Enhanced Conversions
301
+ // 3. Meta Advanced Matching
302
+ }, [userId, email, name]);
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Event naming
308
+
309
+ Read `references/event-tracking.md` → **Recommended Events** and **Parameter
310
+ Rules**. GA4 reserves a set of names and silently drops events that collide
311
+ with them; the reference lists which.
312
+ ## E-commerce
313
+
314
+ Read `references/event-tracking.md` → **Ecommerce Events** for the GA4 item
315
+ schema and the full purchase / add_to_cart / begin_checkout set.
316
+
317
+ **Deduplication is the part that silently doubles revenue.** A purchase fired
318
+ from both the browser and the server (Conversions API, server-side GA4) must
319
+ carry the SAME `event_id` / `transaction_id`, or both are counted. Test it by
320
+ reloading the thank-you page: a purchase that increments twice is a
321
+ deduplication bug, not a tracking success.
322
+ ## Content Security Policy
323
+
324
+ Read `references/performance-security.md` → **Content Security Policy** for the
325
+ full directive set per platform.
326
+
327
+ **The trap:** a nonce on the gtag loader is not enough — Google injects further
328
+ scripts at runtime, so `script-src` needs the Google domains as well, and a CSP
329
+ that passes on the landing page can still break the checkout where the Ads
330
+ conversion tag loads.
331
+ ## Next.js
332
+
333
+ Read `references/gtag-api.md` → **Next.js / React Integration** for the
334
+ component tree, and `references/performance-security.md` → **Script Loading
335
+ Strategies** for `next/script` strategy choice and SPA route changes.
336
+
337
+ **Two traps that are not obvious from either:**
338
+
339
+ - `NEXT_PUBLIC_*` is inlined at **build** time. In a Docker build the variable
340
+ must exist in the builder stage; injecting it at runtime leaves the literal
341
+ string in the bundle and every event goes nowhere.
342
+ - An authenticated area and an embed/widget page need different gating — the
343
+ dashboard already has consent, an embed may have none and must not assume
344
+ the parent page's.
345
+ ## UTM Attribution
346
+
347
+ ### Capture Flow
348
+
349
+ 1. `UtmCapture` component reads UTM params from URL on page load → stores in localStorage
350
+ 2. On registration (credentials): read UTM from localStorage, send in POST body, save to DB
351
+ 3. On registration (OAuth): UTM persists in localStorage through redirect → synced after return via API call
352
+ 4. Mixpanel `people.set_once()` stores initial UTM as permanent user properties
353
+ 5. Clear localStorage after successful DB sync
354
+
355
+ ### UTM Parameters
356
+
357
+ | Parameter | Purpose | Example |
358
+ |---|---|---|
359
+ | `utm_source` | Traffic source | `google`, `facebook`, `newsletter` |
360
+ | `utm_medium` | Marketing medium | `cpc`, `social`, `email` |
361
+ | `utm_campaign` | Campaign name | `spring_sale_2025` |
362
+ | `utm_content` | Ad creative variant | `banner_a`, `text_link` |
363
+ | `utm_term` | Paid search keyword | `ai+chatbot` |
364
+
365
+ ### gclid / fbclid / li_fat_id
366
+
367
+ Google, Meta, and LinkedIn append their own click IDs to URLs:
368
+ - `gclid` — Google Ads click ID (stored in `_gcl_aw` cookie by gtag.js automatically)
369
+ - `fbclid` — Meta click ID (stored in `_fbc` cookie by fbevents.js automatically)
370
+ - `li_fat_id` — LinkedIn click ID (handled by Insight Tag)
371
+
372
+ These are handled automatically by the respective SDKs. Do not strip them from URLs.
373
+
374
+ ---
375
+
376
+ ## Verification
377
+
378
+ Read `references/performance-security.md` → **Debug & Testing** for the full
379
+ per-platform checklist (GA4 DebugView, Meta Test Events, LinkedIn tag helper)
380
+ and the consent round-trip.
381
+
382
+ **The check that catches most of it:** open the site in a fresh incognito
383
+ window, deny consent, and confirm in DevTools → Network that no `_ga` or
384
+ `_gcl_*` cookie is set and that collect requests carry `gcs=G100`. A tag that
385
+ fires correctly *after* consent while ignoring the denied default is the
386
+ failure this whole skill exists to prevent, and it looks fine in every test
387
+ that starts by accepting.
388
+ ## Troubleshooting
389
+
390
+ ### Common Issues
391
+
392
+ | Problem | Cause | Fix |
393
+ |---|---|---|
394
+ | No events in GA4 | Consent defaults not set before gtag.js loads | Ensure consent `default` call is **before** the script tag |
395
+ | CSP violations in console | Missing domain in CSP header | Add the domain to the correct CSP directive |
396
+ | Meta Pixel not firing | Consent-gated component not rendering | Check localStorage consent value, check CustomEvent listener |
397
+ | Duplicate `PageView` events | Multiple pixel instances or route change listeners | Ensure pixel init code has `if(f.fbq)return;` guard |
398
+ | Purchase events without value | Missing `value`/`currency` params | Both GA4 and Meta **require** these for conversion optimisation |
399
+ | Advanced Matching not working | `fbq('init')` called before pixel SDK loads | Ensure `fbevents.js` is loaded before calling `setFbAdvancedMatching()` |
400
+ | Enhanced Conversions not matching | `user_data` set after conversion event | Call `setEnhancedConversionData()` **before** the conversion event fires |
401
+ | gclid lost after Stripe redirect | — (shouldn't happen) | `_gcl_aw` cookie is first-party, persists across redirects |
402
+ | Events firing on localhost | Missing `isLocal` guard | Add `if (window.location.hostname === 'localhost') return;` |
403
+
404
+ ### Debug Mode
405
+
406
+ Enable debug logging for local development:
407
+
408
+ ```typescript
409
+ const isLocal = window.location.hostname === "localhost";
410
+ if (isLocal) {
411
+ console.debug("[Analytics]", eventName, params);
412
+ return; // don't fire real events
413
+ }
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Official documentation
419
+
420
+ Google: [Consent Mode v2](https://developers.google.com/tag-platform/security/guides/consent) ·
421
+ [gtag.js](https://developers.google.com/tag-platform/gtagjs/reference) ·
422
+ [GA4 events](https://developers.google.com/analytics/devguides/collection/ga4/reference/events).
423
+ Meta: [Pixel](https://developers.facebook.com/docs/meta-pixel) ·
424
+ [Conversions API](https://developers.facebook.com/docs/marketing-api/conversions-api).
425
+ LinkedIn: [Insight Tag](https://www.linkedin.com/help/lms/answer/a418880).
426
+ Compliance: [EU DMA](https://digital-markets-act.ec.europa.eu/).
427
+ ## Deep references
428
+
429
+ The sections above are the integration surface across four platforms. When the
430
+ work is specifically Google's tag — and it usually becomes that — these carry
431
+ the depth this file deliberately does not:
432
+
433
+ | File | Read it when |
434
+ |---|---|
435
+ | [`references/consent-mode.md`](references/consent-mode.md) | **consent is the task**: advanced vs basic mode and what each still sends, all consent types, region-specific defaults, granular consent with its localStorage schema, the update flow, GTM wiring, exactly what tags do when denied, URL passthrough, ads data redaction, and how to verify in Tag Assistant / DevTools / DebugView |
436
+ | [`references/gtag-api.md`](references/gtag-api.md) | you are **calling gtag directly**: every command (`config`, `event`, `set`, `get`, `consent`), tag-ID formats, parameter scope and precedence, `send_to` routing and groups, multi-product configuration, and the Next.js App Router integration including the Docker `NEXT_PUBLIC_*` build-time trap |
437
+ | [`references/event-tracking.md`](references/event-tracking.md) | you are **designing the event schema**: recommended vs custom events, naming rules, parameter limits, the item object, the ecommerce funnel, SaaS/subscription events, and a typed `trackEvent` wrapper |
438
+ | [`references/performance-security.md`](references/performance-security.md) | the tag is **costing you Lighthouse points or failing CSP**: loading strategies and their measured impact, CSP directives with and without a nonce, EU region endpoints, SPA page_view handling, and verification in the network tab |
439
+ | [`references/meta-linkedin.md`](references/meta-linkedin.md) | the work is **Meta or LinkedIn rather than Google**: the parameter object per standard event, the firing wrapper and its consent gate, advanced matching with hashed identifiers and what must never be sent, and deduplication against the Conversions API |
440
+
441
+ For the page-speed side of the same problem — what the tag does to LCP and TBT,
442
+ and what to do about it — see the `frontend-performance` skill in this pack.