logo hsb.horse

Architecture Decision Record

Partytown + Google Analytics (GA4) integration policy

Introduce GA4 (G-WZ3RT34EZZ) via Partytown to start pageview measurement while minimizing main-thread impact.

Accepted #analytics #ga4 #partytown #performance #privacy

Partytown + Google Analytics (GA4) integration policy

Decision

  • Adopt Google Analytics 4 (GA4) for traffic analytics, using measurement ID G-WZ3RT34EZZ.
  • Introduce @astrojs/partytown and offload GA script execution to a web worker via type="text/partytown".
  • Centralize analytics tag output in a shared layer (dedicated component under Layout) instead of per-page embedding.
  • Enable tracking only on production URLs; disable it in local development and preview environments.
  • Keep initial scope to pageview tracking only; define custom event taxonomy in a separate ADR.
  • In the initial rollout, do not override gtag('config', ...) privacy parameters and run production with GA4 default settings.

Implementation conventions

ItemRule
Script executionLoad gtag.js with type="text/partytown".
Measurement ID handlingDo not hardcode in page files; inject via PUBLIC_GA_MEASUREMENT_ID (initial value G-WZ3RT34EZZ).
Output conditionEmit tags only when PROD is true and measurement ID is present.
PlacementCentralized in shared Layout, not page-specific.
Event scopeInitial scope is page_view only. No arbitrary custom events in this phase.

Context

Analytics is currently not implemented, so we cannot observe acquisition patterns, page popularity, or content reach. At the same time, third-party scripts running on the main thread can negatively affect TTI/FID/INP.

This project already uses a shared Astro Layout for head-level concerns, so analytics should follow the same pattern. Because the site is multilingual, per-page implementation increases inconsistency risk and should be avoided.

Options

  • Option A: Load standard gtag.js directly on the main thread
  • Option B: Run gtag.js through @astrojs/partytown worker execution (chosen)
  • Option C: Do not adopt GA4 and switch to another lightweight analytics tool

Rationale

  • Performance: Partytown moves third-party script work off the main thread.
  • Operational safety: Shared-layer output prevents missed tags when new pages are added.
  • Incremental rollout: Start with pageviews, then add event design safely in a follow-up ADR.
  • Auditability: Production-only gating and the “start with GA defaults” assumption are explicit and reviewable.

Consequences

  • Add @astrojs/partytown dependency and configure integration in astro.config.mjs.
  • Add a shared analytics component (or equivalent responsibility) referenced from Layout.
  • Define and maintain environment variable operation for PUBLIC_GA_MEASUREMENT_ID.
  • Update privacy policy documentation to disclose GA4 usage and tracking purpose.
  • Acceptance criteria:
    • GA tags are emitted only in production
    • Pageviews are measurable across all public pages
    • Main-thread performance regression stays within acceptable range in Lighthouse (or equivalent)