$npx -y skills add ziniman/ai-instruct --skill google-analytics-4Use this skill whenever the user installs, configures, or debugs Google Analytics 4, or mentions gtag.js, GTM, conversion tracking, e-commerce events, or a cookie/consent banner tied to analytics. Covers installation, event tracking, user properties, e-commerce, Consent Mode v2 f
| 1 | # Google Analytics 4 Implementation Guide |
| 2 | |
| 3 | > Applies to: Any website or web app | Updated: February 2026 |
| 4 | |
| 5 | A practical guide for implementing Google Analytics 4 (GA4) - covering installation, critical first-time setup, event tracking, e-commerce, consent, and advanced topics. Written for AI coding assistants: skip sections that don't apply to the user's setup. |
| 6 | |
| 7 | > **Note:** Universal Analytics (UA / GA3) was fully sunset in 2024. GA4 is the only current Google Analytics product. |
| 8 | |
| 9 | --- |
| 10 | |
| 11 | ## Section 0: Before You Start |
| 12 | |
| 13 | Answer these questions before writing any code. They determine which sections apply. |
| 14 | |
| 15 | **Q: Are any of your visitors in Europe (EU/EEA) or the UK?** |
| 16 | Default: no - if yes, Consent Mode v2 setup is required (see [Consent Mode v2](#consent-mode-v2)) |
| 17 | |
| 18 | **Q: Do you run Google Ads (search, display, YouTube, or Shopping)?** |
| 19 | Default: no - if yes, ad consent signals matter for conversion tracking and which events you mark as conversions |
| 20 | |
| 21 | **Q: Is your site a single-page app (React, Vue, Angular, Next.js, etc.) where the URL changes without a full page reload?** |
| 22 | Default: check the project for `package.json`, `next.config.*`, `vite.config.*`, `angular.json`, or `nuxt.config.*` - if found, assume SPA and apply the [Single-Page Apps](#single-page-apps) section automatically |
| 23 | |
| 24 | **Q: Do you need to track purchases or sales?** |
| 25 | Default: no - skip [E-commerce Tracking](#e-commerce-tracking) if no |
| 26 | |
| 27 | **Q: Do you already have a GA4 property, or is this a fresh start?** |
| 28 | Default: fresh start - if fresh start, create a property at analytics.google.com before writing any code |
| 29 | |
| 30 | **Q: Do you use Google Tag Manager, or add the tracking code directly?** |
| 31 | Default: direct gtag.js - recommend GTM only if the user has a marketing team managing multiple tags |
| 32 | |
| 33 | > **AI assistant:** Use these answers to skip irrelevant sections. Do not implement Consent Mode unless the user confirms EU/EEA/UK users. Do not implement e-commerce unless confirmed. If a SPA framework is detected in the project, automatically apply the SPA page_view section. Do not add `anonymize_ip` - it is a no-op in GA4 (see [Common Pitfalls](#common-pitfalls)). |
| 34 | |
| 35 | --- |
| 36 | |
| 37 | ## Contents |
| 38 | |
| 39 | 1. [Installation](#installation) |
| 40 | 2. [Basic Configuration](#basic-configuration) |
| 41 | 3. [Critical First-Time Setup](#critical-first-time-setup) |
| 42 | 4. [Common Pitfalls](#common-pitfalls) |
| 43 | 5. [Event Tracking](#event-tracking) |
| 44 | 6. [Enhanced Measurement](#enhanced-measurement) |
| 45 | 7. [User Properties & Custom Dimensions](#user-properties--custom-dimensions) |
| 46 | 8. [E-commerce Tracking](#e-commerce-tracking) |
| 47 | 9. [Consent Mode v2](#consent-mode-v2) |
| 48 | 10. [Single-Page Apps](#single-page-apps) |
| 49 | 11. [Debugging](#debugging) |
| 50 | 12. [Validation & Testing](#validation--testing) |
| 51 | 13. [Advanced: BigQuery Export & Sampling](#advanced-bigquery-export--sampling) |
| 52 | |
| 53 | --- |
| 54 | |
| 55 | ## Installation |
| 56 | |
| 57 | ### Option A: gtag.js (direct) |
| 58 | |
| 59 | Add to `<head>` on every page. Replace `G-XXXXXXXXXX` with your Measurement ID (found in GA4 > Admin > Data Streams): |
| 60 | |
| 61 | ```html |
| 62 | <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script> |
| 63 | <script> |
| 64 | window.dataLayer = window.dataLayer || []; |
| 65 | function gtag(){ dataLayer.push(arguments); } |
| 66 | gtag('js', new Date()); |
| 67 | gtag('config', 'G-XXXXXXXXXX'); |
| 68 | </script> |
| 69 | ``` |
| 70 | |
| 71 | ### Option B: Google Tag Manager |
| 72 | |
| 73 | GTM lets non-developers add and update tags without code changes. Add to `<head>` and immediately after `<body>`: |
| 74 | |
| 75 | ```html |
| 76 | <!-- In <head> --> |
| 77 | <script> |
| 78 | (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': |
| 79 | new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], |
| 80 | j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= |
| 81 | 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); |
| 82 | })(window,document,'script','dataLayer','GTM-XXXXXXX'); |
| 83 | </script> |
| 84 | |
| 85 | <!-- First thing in <body> (fallback for no-JS environments) --> |
| 86 | <noscript> |
| 87 | <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" |
| 88 | height="0" width="0" style="display:none;visibility:hidden"></iframe> |
| 89 | </noscript> |
| 90 | ``` |
| 91 | |
| 92 | **gtag.js vs GTM:** Use gtag.js for simple setups or full code control. Use GTM when a marketing or analytics team needs to add tags independently, or when you manage more than two or three tags across different vendors. |
| 93 | |
| 94 | --- |
| 95 | |
| 96 | ## Basic Configuration |
| 97 | |
| 98 | Pass options as the third argument to `gtag('config', ...)`: |
| 99 | |
| 100 | ```javascript |
| 101 | gtag('config', 'G-XXXXXXXXXX', { |
| 102 | // Disable automatic page_view - set to false when firing it manually (e.g. SPAs |