Skip to content

feat: GA4 acquisition analytics (gtag.js, env+host gated, manual pageviews) - #63

Merged
Aliferous3 merged 1 commit into
mainfrom
feat/ga4-acquisition
Sep 29, 2026
Merged

Aliferous3 merged 1 commit into
mainfrom
feat/ga4-acquisition

Conversation

@Aliferous3

Copy link
Copy Markdown
Owner

Summary

  • Adds Google Analytics 4 as the acquisition/marketing layer alongside PostHog (which stays the product-behavior system, fully untouched).
  • New src/analytics/ga4Model.mjs + src/analytics/ga4.ts: silent no-op without VITE_GA_MEASUREMENT_ID; official telemetry only on devledger.site (localhost runs debug_mode); send_page_view:false with manual pathname-deduped page_view built from canonical origin + normalized pathname — location.href, query strings and fragments never reach GA4.
  • Strict event allowlist: page_view, login_start, login, select_content — all schema-validated, method:"github" only, no identity/user_id.
  • UTM handling: only the five utm_* fields are read, slug-sanitized, and lifted into GA4's documented campaign_* dimensions via gtag('set', …); page_location stays clean.
  • Minimal CSP expansion: www.googletagmanager.com (script/img), www.google-analytics.com + region1.google-analytics.com (connect/img). No GTM, no Ads, no Signals, no remarketing.
  • Legal updates in Privacy, Security, and Terms disclose exactly what is collected (including _ga cookies).
  • 24-case test suite: ID hygiene, host gating, sanitization, StrictMode/query/hash dedupe, UTM rules, hostile params, wiring, PostHog separation.

Test plan

  • npm run typecheck clean; npm test 475 pass / 0 fail; npm run build green
  • dist/ scan: no G-… measurement ID in committed bundle
  • Production QA + GA4 Realtime verification after env var is set in Vercel

Generated with Devin

…al pageviews)

Adds Google Analytics 4 as the acquisition/traffic-source layer alongside
PostHog (which remains the product-behavior system, untouched).

- src/analytics/ga4Model.mjs: pure validation/sanitization — measurement-ID
  format check, devledger.site production gate + localhost debug gate,
  canonical pathname normalization, page_location/page_title params, strict
  event allowlist (page_view, login_start, login, select_content), and
  utm_*→campaign_* field mapping with slug-charset sanitization.
- src/analytics/ga4.ts: typed facade — lazy init only when
  VITE_GA_MEASUREMENT_ID is set and the host is devledger.site (localhost
  runs debug_mode), send_page_view:false, async gtag.js from
  googletagmanager.com only, pathname-deduped manual page_view, never
  throws. No User-ID, no identify, no Signals/ads features.
- Wiring: boot init+pageview+popstate in main.tsx; navigate/popstate
  pageviews in pages.ts; login_start on the GitHub button and login on
  the post-OAuth successful boot — method:"github" only, zero identity.
- CSP: adds www.googletagmanager.com (script-src, img-src) and
  www.google-analytics.com + region1.google-analytics.com
  (connect-src, img-src) — the minimum for direct gtag.js collection.
- Env: VITE_GA_MEASUREMENT_ID joins the public-env allowlist;
  .env.example documents the name with an empty placeholder. The real ID
  lives only in Vercel env config.
- Legal: Privacy/Security/Terms disclose GA4 — sanitized pageviews,
  campaign fields, login funnel, _ga cookies, disabled features.
- Tests: 24-case suite covering ID hygiene, host gating, sanitization,
  event allowlist, UTM rules, wiring, and PostHog separation.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
dev-ledger Ready Ready Preview Sep 29, 2026 10:14pm UTC

@Aliferous3
Aliferous3 merged commit 42a7d12 into main Sep 29, 2026
5 checks passed
@Aliferous3
Aliferous3 deleted the feat/ga4-acquisition branch September 29, 2026 22:20

This branch was successfully deployed

1 active deployment
Preview — 5859d3a0 Deployed Sep 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant