{"id":11890,"library":"react-tracking","title":"Declarative Tracking for React Apps","description":"react-tracking is a declarative and imperative tracking library specifically designed for React applications. It provides an analytics platform-agnostic solution, empowering developers to manage and dispatch user interaction data effectively. The library's core philosophy is to compartmentalize tracking concerns directly within individual components, thereby preventing data leakage and ensuring a clean separation of concerns across the entire application. It offers a dual API approach, supporting both the traditional Higher-Order Component (HoC) or decorator pattern and a modern React Hooks API, which was fully introduced in version 8.1.0 for functional components. The current stable version, 9.3.2, has recently addressed compatibility issues with React Native environments and re-enabled support for Node.js 16.9+. Developed by The New York Times, react-tracking is actively maintained, with a consistent cadence of patch and minor releases addressing bug fixes and introducing new features like `mergeOptions` (v9.3.0) and `deepmerge` re-export (v9.2.0). Its key differentiators include its highly declarative nature, flexibility to integrate seamlessly with virtually any analytics backend, and comprehensive support for both class-based and modern functional React components, making it a versatile choice for instrumenting React UIs.","status":"active","version":"9.3.2","language":"javascript","source_language":"en","source_url":"https://github.com/nytimes/react-tracking","tags":["javascript","declarative","layer","metrics","nyt","react","tracking"],"install":[{"cmd":"npm install react-tracking","lang":"bash","label":"npm"},{"cmd":"yarn add react-tracking","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-tracking","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for all React component usage (HoCs, Hooks).","package":"react","optional":false},{"reason":"Peer dependency for type checking in React components, common for HoC/decorator usage.","package":"prop-types","optional":true}],"imports":[{"note":"`track` is the default export, primarily used for the Higher-Order Component (HoC) or decorator pattern with class components.","wrong":"import { track } from 'react-tracking';","symbol":"track","correct":"import track from 'react-tracking';"},{"note":"A named export for the React Hooks API, introduced in v8.1.0, for use with functional components. ESM-only usage is preferred.","wrong":"const { useTracking } = require('react-tracking');","symbol":"useTracking","correct":"import { useTracking } from 'react-tracking';"},{"note":"`Track` is a component returned by the `useTracking` hook, used to explicitly wrap JSX and pass contextual tracking data to child components.","wrong":"import { track } from 'react-tracking';","symbol":"Track","correct":"import { Track } from 'react-tracking';"},{"note":"Re-exported for convenience since v9.2.0, useful when providing custom `mergeOptions` or needing deep merging capabilities with tracking data.","wrong":"import deepmerge from 'deepmerge';","symbol":"deepmerge","correct":"import { deepmerge } from 'react-tracking';"}],"quickstart":{"code":"import React, { useEffect } from 'react';\nimport { useTracking, Track } from 'react-tracking';\n\ninterface MyComponentProps {\n  userId: string;\n  pageName: string;\n}\n\nconst ProductPage: React.FC<MyComponentProps> = ({ userId, pageName }) => {\n  // Initialize tracking for this component, passing contextual data\n  const { Track, trackEvent, getTrackingData } = useTracking(\n    {\n      page: pageName,\n      user: userId,\n      environment: process.env.NODE_ENV ?? 'development',\n    },\n    {\n      // Optional: Dispatch tracking data when component mounts\n      dispatchOnMount: true,\n      // Optional: Custom merge options for tracking objects (since v9.3.0)\n      mergeOptions: {\n        isMergeableObject: obj => !(obj instanceof Date || obj instanceof RegExp),\n      },\n    }\n  );\n\n  useEffect(() => {\n    // Example: Log current tracking data when component mounts\n    console.log('Current tracking context:', getTrackingData());\n  }, []);\n\n  const handleProductClick = (productId: string) => {\n    // Imperatively dispatch an event\n    trackEvent({\n      action: 'product_click',\n      productId: productId,\n      timestamp: new Date().toISOString(),\n    });\n  };\n\n  return (\n    <Track> {/* Use <Track> to pass context to children */}\n      <div>\n        <h1>{pageName} for User: {userId}</h1>\n        <p>This is a product page example.</p>\n        <button onClick={() => handleProductClick('product-123')}>\n          Click to Track Product 123\n        </button>\n        <button onClick={() => trackEvent({ action: 'promo_view', promoId: 'summer_sale' })}>\n          Track Promo View\n        </button>\n      </div>\n    </Track>\n  );\n};\n\n// Example of usage:\n// <ProductPage userId=\"user-abc\" pageName=\"Electronics-Category\" />\nexport default ProductPage;","lang":"typescript","description":"Demonstrates how to use the `useTracking` hook to declare component-level tracking data, imperatively dispatch events with `trackEvent`, access contextual data with `getTrackingData`, and use the `<Track>` component to propagate context to child components. It also shows options like `dispatchOnMount` and `mergeOptions`."},"warnings":[{"fix":"Ensure your application's build process or entry points include necessary polyfills (e.g., via `core-js`, Babel, or polyfill.io) if your target browsers require them.","message":"Version 9.0.0 removed `core-js` polyfills from the bundle to reduce build size. Applications must now provide their own polyfills if targeting older browser environments.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"For decorator usage, pass `{ forwardRef: true }` as the second argument: `@track({}, { forwardRef: true })`. This allows `ref` to correctly point to the decorated component instance.","message":"When using the HoC/decorator pattern, accessing the underlying component's ref requires explicitly setting `forwardRef: true` in the options. Failing to do so will result in the ref pointing to the HoC wrapper instead of the intended component.","severity":"gotcha","affected_versions":">=8.0.0"},{"fix":"Upgrade to `react-tracking@7.3.0` or newer. If stuck on older versions, ensure decorated async methods explicitly return their original promise or handle `trackEvent` calls carefully.","message":"Prior to v7.3.0, decorating asynchronous methods (or methods returning Promises) could lead to incorrect return values or `TypeError` exceptions if `trackEvent` was called with `null`.","severity":"gotcha","affected_versions":"<7.3.0"},{"fix":"Ensure the `dispatchOnMount` function is optimized for performance and idempotent, as it runs on every initial render. Avoid unnecessary complex logic within this function.","message":"When `dispatchOnMount` is provided as a function, it is called in a `useEffect` on the component's initial render with all tracking context data. Be mindful of potential side effects or performance implications if the function performs heavy operations.","severity":"gotcha","affected_versions":"*"},{"fix":"Upgrade to `react-tracking@9.3.1` or newer if your project relies on Node.js 16.9+ environments.","message":"Version 9.3.0 of `react-tracking` temporarily dropped support for Node.js 16.9+ due to an oversight, only to re-enable it in 9.3.1. Ensure you are on 9.3.1 or later if using Node.js 16.9+.","severity":"gotcha","affected_versions":"9.3.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Upgrade `react-tracking` to version `7.3.0` or newer. If unable to upgrade, ensure your decorated async methods handle potential `null` or `undefined` values when calling `trackEvent`.","cause":"Decorating an async method in `react-tracking` versions prior to 7.3.0 could lead to `trackEvent` being called with `null` or an unexpected value when an error occurred.","error":"TypeError: Cannot destructure property `trackEvent` of 'null' or 'undefined'"},{"fix":"Ensure `useTracking` is only invoked directly within the body of a React functional component or another custom React Hook function. Do not call Hooks from regular JavaScript functions, class components, or event handlers directly.","cause":"`useTracking` or other React Hooks are being called outside of a functional React component or a custom Hook.","error":"Error: Invalid hook call. Hooks can only be called inside of the body of a function component."},{"fix":"Run `npm install --save react-tracking` or `yarn add react-tracking`. Double-check the import statement for any typos, ensuring it is `import { useTracking } from 'react-tracking';` or `import track from 'react-tracking';`.","cause":"The `react-tracking` package is not installed, or there is a typo in the import path.","error":"Module not found: Error: Can't resolve 'react-tracking'"}],"ecosystem":"npm"}