本文へ移動
cccskills
無料GitHub で公開

analytics-tracking

Designs and implements website analytics tracking with Google Analytics 4 and Google Tag Manager: a written tracking plan, event and parameter names that pass GA4's rules, gtag.js or data-layer code, key events, consent mode, UTM conventions, and a verification pass. Use when someone says "set up GA4", "add conversion tracking", "track this form or button", "write a tracking plan", "GTM data layer", "UTM parameters", "why are my events missing or counted twice", or "audit our analytics setup".

インストール方法を見る

含まれるファイル(2)

  • SKILL.md16.2 KB
  • _scores.json1.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Analytics Tracking

Overview

Tracking is finished when a named person can answer a business question from a report, not when a tag fires. This skill takes a site from "we have GA4 installed" to a short tracking plan, code that sends each event exactly once with valid names, the Admin settings that make the data usable, and proof that it works. Everything here follows Google's current documentation for GA4, the Google tag and Tag Manager; Universal Analytics concepts (categories, actions, labels, goals, anonymize_ip) do not apply.

Instructions

1. Establish what exists

Ask: which decisions the data should inform, which actions count as success (lead, signup, purchase), which regions the visitors come from (consent), and who is allowed to publish the Tag Manager container. Then look in the code:

grep -rnE "gtag\(|dataLayer\.push|googletagmanager\.com|GTM-[A-Z0-9]{4,}|G-[A-Z0-9]{8,}|@next/third-parties" \
  --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.html" \
  --exclude-dir=node_modules --exclude-dir=.next .

Choose one delivery path and keep to it. If a GTM- container is on the page, send events through the data layer and configure tags in Tag Manager; if only the Google tag is present, call gtag() directly. The same event sent through both paths is counted twice.

2. Pick events from the top of this list down

  1. Already collected. With enhanced measurement on, GA4 records page_view (page loads and browser-history changes), scroll (once per page at 90% depth), click (outbound links only), view_search_results, video_start / video_progress / video_complete (embedded YouTube), file_download, form_start and form_submit. Do not re-implement these.
  2. Recommended events. Use Google's exact names and parameters so built-in reports fill in: sign_up and login (method), generate_lead (currency, value, lead_source), search (search_term), view_item, add_to_cart, begin_checkout, add_payment_info, purchase (transaction_id, currency, value, items).
  3. Custom events, only when nothing above fits. One name per action, with the variation in parameters: cta_click with cta_location: "pricing_hero", not a separate event name per button.

Names must pass these limits; GA4 does not log what exceeds them, and nothing in the browser reports an error:

ItemRule
Event nameStarts with a letter; letters, digits and underscores only; case-sensitive; 40 characters
Parameters25 per event; name 40 characters; value 100 characters (page_location 1,000, page_referrer 420, page_title 300)
User properties25 per property; name 24 characters; value 36 characters
ReservedParameter names starting with _, firebase_, ga_, google_ or gtag.. Do not reuse automatic names (click, scroll, session_start, first_visit, user_engagement, form_submit, file_download) for custom events
Per standard property30 key events, 50 event-scoped and 25 user-scoped custom dimensions, 50 custom metrics

Money: value is a number, never a string, and always travels with currency (ISO 4217, "USD"). For purchase, value is the sum of price × quantity and excludes shipping and tax; transaction_id is required and is what keeps a repeated purchase from being counted again.

3. Write the tracking plan

Create docs/tracking-plan.md with one row per event: event name, the exact moment it fires (a server-confirmed success, not a button press), parameters with example values, whether it is a key event, and which path sends it. Example 1 shows the format. Every later step works from this file.

4. Implement

Google tag with consent defaults. The consent default must run before the tag loads; the order of these blocks is the point.

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('consent', 'default', {
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    analytics_storage: 'denied',
    wait_for_update: 500
  });
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7KQ2M4XW9P"></script>
<script>
  gtag('js', new Date());
  gtag('config', 'G-7KQ2M4XW9P');
</script>

When the visitor answers the banner, the consent tool calls gtag('consent', 'update', { analytics_storage: 'granted', ... }) with all four types, and repeats that on later pages from the stored choice. Add region: ['ES', 'FR'] to a default to scope it; the most specific region wins. Which defaults to set is the site owner's legal decision, not a technical one. In Tag Manager, use a consent template from the Community Template Gallery (or the consent APIs in a custom template), never a Custom HTML tag.

Events with gtag.js go anywhere below the snippet: gtag('event', 'generate_lead', { currency: 'USD', value: 180, lead_source: 'demo_form' }).

Events with Tag Manager. The page pushes a message that carries an event key; a GA4 Event tag listens for it with a Custom Event trigger and reads the fields through Data Layer Variables. For ecommerce events, clear the previous object first:

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'ST-20418',
    value: 43.50,
    tax: 3.48,
    shipping: 4.90,
    currency: 'USD',
    items: [
      { item_id: 'OOL-100', item_name: 'High Mountain Oolong 100 g', price: 14.50, quantity: 3 }
    ]
  }
});

Single-page apps. Enhanced measurement sends page_view on pushState, popState and replaceState when "Page changes based on browser history events" is ticked (Admin > Data collection and modification > Data streams > the stream > Enhanced measurement > Page views > advanced settings). With Tag Manager, send page_view from a GA4 Event tag on a History Change trigger and leave that option off, or every navigation counts twice. To send page views by hand, set send_page_view: false in config and turn the history option off as well.

Signed-in users. Pass an internal ID with gtag('config', 'G-7KQ2M4XW9P', { user_id: 'u_48211' }): an opaque ID, never an email address.

Server-side events (a webhook confirms payment, a CRM marks a lead qualified) go through the Measurement Protocol: POST https://www.google-analytics.com/mp/collect?measurement_id=...&api_secret=... with a JSON body holding client_id and up to 25 events. Read the browser's client_id and session_id with gtag('get', 'G-7KQ2M4XW9P', 'client_id', callback) and store them with the order. Include session_id and engagement_time_msec in params; without them the event does not count toward session and engagement metrics or show properly in Realtime. The secret is created under Admin > Data collection and modification > Data streams > the stream > Measurement Protocol API secrets and stays in a server environment variable. For EU collection use the host region1.google-analytics.com.

5. Configure GA4 Admin

  • Key events (the name that replaced "conversions"): Admin > Data display > Events, star the event. purchase is one by default. Allow up to 24 hours for standard reports.
  • Custom definitions: a custom parameter is invisible in reports until it is registered under Admin > Data display > Custom definitions as an event-scoped dimension; it appears 24–48 hours later. Register only what the plan needs.
  • Data retention: Admin > Data Settings > Data Retention. Standard properties offer 2 or 14 months; choose 14. It affects explorations and funnels, not the standard aggregated reports.
  • Data redaction: turn on email redaction and list query parameters to strip for the web stream if URLs can carry personal data.

6. Set the UTM convention

ParameterUse
utm_sourceWho sent the visit: newsletter, linkedin, partner-fieldnotes
utm_mediumChannel type; GA4 maps it to a default channel (table below)
utm_campaignThe campaign, identical across every platform it runs on
utm_idCampaign ID, needed when cost data is imported
utm_content, utm_termCreative variant; paid keyword

Always set source, medium and campaign together. Values are case-sensitive (Email and email become two rows), so use lowercase throughout. Keep UTMs off links between your own pages and never put personal data in them.

utm_medium valueDefault channel group
emailEmail
cpc, ppc, or anything starting with paidPaid Search, Paid Social, Paid Shopping, Paid Video or Paid Other, depending on the source
socialOrganic Social
affiliateAffiliates
display, banner, cpmDisplay
referralReferral
smsSMS

7. Verify before calling it done

  1. Open Tag Assistant (tagassistant.google.com, or Preview in the Tag Manager workspace), connect to the site, and perform each action in the plan.
  2. Watch Admin > Data display > DebugView. Each event must appear once, with every planned parameter, on desktop and on a phone. DebugView stays empty while analytics consent is denied, so grant it in the banner first.
  3. To debug without Tag Assistant, add debug_mode: true to the event or config; remove the key afterwards, because setting it to false does not switch it off.
  4. Check server-side payloads against the validation server (Example 3). The live endpoint returns 2xx even for malformed events.
  5. A day later, confirm the events and key events in the standard reports and record the date in the plan.

Examples

Example 1: Lead tracking for a B2B site on Next.js

Prompt: "Kestrel Payroll's marketing site is Next.js. GA4 is installed with the Google tag. We need demo requests and signups as conversions, and we want to know which company sizes ask for demos."

The plan the agent writes to docs/tracking-plan.md:

| Event | Fires when | Parameters (example) | Key event | Sent by |
|---|---|---|---|---|
| page_view | page load and route change | automatic | no | enhanced measurement |
| file_download | click on a PDF link | automatic | no | enhanced measurement |
| generate_lead | POST /api/demo returns 200 | currency "USD", value 180, lead_source "demo_form", company_size "51-200" | yes | gtag |
| sign_up | account row created | method "email" or "google" | yes | gtag |
| cta_click | click on a primary button | cta_location "pricing_hero", cta_text "Start free trial" | no | gtag |

Custom dimensions to register (event scope): company_size, cta_location, lead_source
Lead value: 180 USD = 6% demo-to-customer rate × 3,000 USD first-year revenue
Verified in DebugView: 2026-10-02

The code:

// app/layout.tsx — loads the Google tag once for every route
import { GoogleAnalytics } from '@next/third-parties/google'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_ID!} />
    </html>
  )
}

// app/demo/DemoForm.tsx — fire only after the server accepted the request
'use client'
import { sendGAEvent } from '@next/third-parties/google'

export async function submitDemo(form: { email: string; companySize: string }) {
  const res = await fetch('/api/demo', { method: 'POST', body: JSON.stringify(form) })
  if (!res.ok) return
  sendGAEvent('event', 'generate_lead', {
    currency: 'USD',
    value: 180,
    lead_source: 'demo_form',
    company_size: form.companySize, // the email address is never sent
  })
}

Then the Admin steps: star generate_lead and sign_up as key events, register the three custom dimensions, set retention to 14 months, confirm "Page changes based on browser history events" is ticked so App Router navigations count as page views.

Example 2: A store that counts purchases twice

Prompt: "Saltmarsh Tea runs on a custom storefront with Tag Manager. GA4 shows about 30% more purchases than our order system."

The agent searches the code, finds the purchase push in the order-confirmation page with no transaction_id, and a second GA4 tag firing on the same page from a Page View trigger. Customers who reload the confirmation page, or reopen it from the order email, send the event again. The fix:

  1. Push purchase once, with transaction_id set to the order number and the ecommerce: null reset before it (the code in step 4).
  2. In Tag Manager keep one GA4 Event tag for purchase on a Custom Event trigger named purchase, map transaction_id, value, currency and items from Data Layer Variables, and delete the Page View tag.
  3. Preview, place a test order, reload the confirmation page, and confirm in Tag Assistant that the tag fired once.
  4. Compare GA4 purchases with the order system for the following week and note the remaining gap in the plan. After the fix GA4 should match the order system or sit below it, because ad blockers and declined consent only remove events.

Example 3: Checking a server-side event before it ships

The validation server accepts the same request as the live endpoint, stores nothing, and explains what is wrong. It does not check the secret or the measurement ID.

curl -s -X POST "https://www.google-analytics.com/debug/mp/collect?measurement_id=G-7KQ2M4XW9P&api_secret=$GA_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"1837264019.1759312800","validation_behavior":"ENFORCE_RECOMMENDATIONS",
       "events":[{"name":"Demo Request","params":{"value":180}}]}'
{
  "validationMessages": [ {
    "fieldPath": "events",
    "description": "Event at index: [0] has invalid name [Demo Request]. Only alphanumeric characters and underscores are allowed.",
    "validationCode": "NAME_INVALID"
  } ]
}

Renamed to generate_lead with currency, value, session_id and engagement_time_msec, the same request returns an empty validationMessages array. Only then does the agent switch the URL to /mp/collect.

Guidelines

  • No personal data in any event, parameter, user property, page URL, page title or UTM value: no emails, phone numbers or names. Look for forms that submit with GET and put the email in the query string.
  • A parameter that is not registered as a custom dimension cannot be used in reports, and one registered late has no history. Register on the day the event ships.
  • A parameter value over 100 characters exceeds the collection limit and is not stored as sent. Send IDs and short labels, not sentences.
  • Do not spend key events on steps (page views, clicks). Thirty is the ceiling, and each one dilutes the "Key events" column.
  • Fire on confirmed outcomes. A click on "Submit" also counts validation errors and double clicks; the server's success response does not.
  • GA4 does not log IP addresses, so there is no IP-anonymisation switch to set. Old snippets containing anonymize_ip can be deleted.
  • Keep debug traffic out of reports: use Tag Assistant for your own device instead of shipping debug_mode to everyone.
  • Never put the Measurement Protocol secret in browser code. Anyone who has it can write events into the property.
  • This skill does not decide what the consent banner must say or which defaults are lawful in a given country; that belongs to the site owner and their counsel.
  • Not the right tool for product analytics inside an app (per-user funnels, retention cohorts) or for mobile SDK setup.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Scripts and configures production rendering in Autodesk 3ds Max with the V-Ray and Corona renderers: output size and files, render elements, denoising, light mix, batch and command-line rendering, and network rendering. Use when a user asks to set up a production render, render several cameras in one batch, render from the command line or on a render farm, add render passes for compositing, or cut render time for archviz and product shots.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Covers scripting Autodesk 3ds Max, the 3D modeling and rendering application, with MAXScript and Python (pymxs): scene manipulation, object creation, material assignment, camera and light setup, batch operations, and file I/O. Use when tasks involve automating repetitive 3ds Max workflows, batch processing scenes, running scripts headless with 3dsmaxbatch, creating custom tools, or scripting scene setup for archviz, product visualization, or VFX.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

3proxy

無料

3proxy is a small open-source proxy server that runs HTTP/HTTPS, SOCKS4/5, SNI and TCP/UDP port-mapping proxies from one config file. Use when a user asks to set up an HTTP or SOCKS5 proxy, add proxy users and passwords, write 3proxy access rules, chain or rotate upstream (parent) proxies, limit bandwidth, connections or monthly traffic per user, run 3proxy in Docker, or fix a 3proxy.cfg that will not start.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Builds Agent2Agent (A2A) servers and clients, the open protocol (originally from Google, now under the Linux Foundation) that lets AI agents from different frameworks call each other. Use when the user wants to create an A2A-compliant agent, build an Agent Card, implement task management, connect agents across frameworks, set up agent discovery, handle streaming responses, implement push notifications, or orchestrate multi-agent workflows. Trigger words: a2a, agent to agent, agent2agent, a2a protocol, a2a server, a2a client, agent card, agent interoperability, agent collaboration, multi-agent, agent discovery, a2a sdk, a2a task.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Plans a controlled experiment (A/B test) so its result can be trusted: writes the hypothesis, picks one primary metric and the guardrails, computes sample size and run time, specifies how visitors are assigned and when exposure is logged, and reads out the result with a confidence interval. Use when someone says "set up an A/B test", "split test this page", "how many visitors do I need", "how long should the experiment run", "is this result significant", "can I stop the test early", or wants to test a headline, price, layout or onboarding change against the current version.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

ably

無料

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token authentication, presence, history and rewind, batch publishing, and the @ably/chat 1.x SDK.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

TerminalSkills のスキルをすべて見る

このスキルの問題を報告する