react-ga

A lightweight wrapper around Google Universal Analytics that gives React apps pageview, event, timing, and outbound-link tracking with a testable API.

SDK
npm
v3.3.1
5,098stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
46/100Fair
Development Activity0
Maintenance20
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture70
Code Quality80
Innovation55
Learning Curve70

react-ga is a thin JavaScript module that standardizes how a React codebase talks to Google’s Universal Analytics analytics.js library. Rather than hand-writing raw ga('send', ...) calls, it exposes named functions — initialize, pageview, event, modalview, timing, exception, and set — that map directly onto GA hit types, plus a <OutboundLink> component for click-tracked external links.

It supports sending the same hit to multiple GA trackers at once, redacts email-shaped strings out of event data by default, and ships a testMode that swaps window.ga for an in-memory API so tracking calls can be asserted in Jest without touching a real GA property. It is explicitly built for Universal Analytics and does not address GA4’s gtag.js/Measurement Protocol model.

What You Get

  • Wrapper functions for every core Universal Analytics hit type: pageview, event, modalview, timing, exception, and set.
  • A ready-made <OutboundLink> React component for click-tracked outbound links with a safety-timeout fallback.
  • Multi-tracker support so the same app can send hits to more than one GA property at once.
  • A test-mode API (testModeAPI) for asserting tracking calls in unit tests without touching a real GA account.

Common Use Cases

  • Tracking pageviews on route changes in single-page apps built with react-router.
  • Recording outbound link clicks for attribution on marketing and content pages.
  • Logging user interaction events (button clicks, form submits) as GA events.
  • Measuring custom timings, like AJAX request duration or CDN load time.

Under The Hood

Architecture The package is a small module set: src/core.js holds nearly all the public API as top-level exported functions (initialize, ga, set, send, pageview, modalview, timing, event, exception, plugin, outboundLink) built around one internal internalGa gateway that switches between the real window.ga, a TestModeAPI mock (test mode), or a no-op warning (non-browser/SSR); src/index.js re-exports each of these individually and binds the <OutboundLink> component’s static trackLink method to core’s outboundLink, the one place presentation (React) and tracking logic touch. Configuration state (_debug, _titleCase, _testMode, etc.) lives as module-level closures rather than a class or context, so the module behaves as a singleton — one initialize() call configures every subsequent call site. Swapping the core internalGa abstraction would require rewriting every exported tracking function, since none of them call window.ga directly.

Tech Stack Authored in plain ES modules with Babel (@babel/preset-env, @babel/preset-flow, @babel/preset-react), transpiled to a UMD bundle via Webpack 4 and a separate ESM build under dist/esm; React and prop-types are declared as peer dependencies rather than bundled, so the module stays framework-version-agnostic across React 15 through 18. Hand-authored TypeScript typings live in types/index.d.ts and are exercised by a standalone types/react-ga-tests.ts file compiled via tsc. Releases are cut with semantic-release off conventional commits, and a version-bower.js script keeps a legacy bower.json copy in sync for script-tag consumers.

Code Quality Test coverage is extensive and organized by concern — one file per public function under test/functionality/ plus a test/utils/ suite for each internal helper — run with Jest and Enzyme for the <OutboundLink> component, with coverage collected on every run. Error handling is explicit and consistent: nearly every exported function validates its arguments and calls a shared warn() helper rather than throwing, so misuse degrades to a console warning instead of crashing the host app. Linting runs through ESLint’s airbnb config plus Prettier, wired into a Husky pre-commit hook, and CI runs build, lint, test, and type-check on every pull request — though the module itself is untyped JavaScript, with types provided only as a hand-maintained overlay.

API Design The public API is intentionally more verbose than calling ga() directly — e.g. ReactGA.event({ category, action, label, value }) versus a raw ga('send', 'event', ...) call — trading terseness for self-documenting call sites, and every tracking function accepts an optional list of tracker names so multi-tracker fan-out never requires hand-managing GA’s tracker-name-prefixing convention. Getting started requires exactly one initialize() call before anything else works, with no provider or context wrapper needed — a bare function-call API plus one drop-in component. The library is explicitly scoped to Universal Analytics and does not address the newer GA4 model, which limits it as a forward-looking abstraction even though the existing surface is clear and well documented.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search