react-capture-metrics v1.1.1
react-capture-metrics
Table of Contents:
Introduction
The react-capture-metrics package is a small react library to help pass properties to your analytics via context.
The problem it solves is probably best demonstrated in an example. (Or check out the Code Sandbox)
// Deep down at the most granular level of your react app
// you want to track a button click
<button onClick={analytics.track('Add to cart')}>
Add to cart
</button>
// But you also want to know which product,
// by which user,
// on which page,
// in which variant of an a/b test and more
<button onClick={analytics.track('Add to cart', {
user: { /* user props */ },
variantId,
pageName, // document.title might change with other copy
utmCode,
productRankInList,
/// ...and more!
})}>
Add to cart
</button>All those extra properties would lead to a lot of prop-drilling or superfluous use of react context. This solves that problem.
Instead, we add properties throughout the virtual DOM and properties get passed down to nested components via context. It sort of imitates Event bubbling and capture. Hence, the name - we are capturing properties down the DOM tree hierarchy.
For example:
- Get
utmCodefromapp.tsx - Get
sessionIdfromauth.tsx - Get
userfromuser.tsx - Get
variantIdfrompage.tsx
Then in your button you only have to call:
<button onClick={analytics.track('Add to cart')}>
Add to cart
</button>Example
Quick Start
Inside your React project directory, run the following:
yarn add react-capture-metricsOr with npm:
npm install react-capture-metricsMount MetricsProvider
import { MetricsProvider } from 'react-capture-metrics'
const analytics = {
track: (name, properties) => window.analytics.track(name, properties),
page: (name, properties, category) => window.analytics.page(...(category ? [category, name, properties] : [name, properties]))
}
function App () {
return (
<MetricsProvider analytics={analytics} properties={{ appVersion: pkg.version }}>
// ...the rest of your app
</MetricsProvider>
)
}In the above example, an analytics object (with track and page methods) that conforms to the react-capture-metrics spec, and translates to the Segment API specification.
** Note that analytics should be defined outside of component or via a ref because MetricsProvider will not watch for updates.
useMetrics()
import { useMetrics } from 'react-capture-metrics';
function Page() {
const {
analytics,
Capture,
PageView,
} = useMetrics({
// ...properties to pass down
})
}Parameters
properties: all properties you want to "inject" into the DOM hierarchy (using theCaptureorPageViewcomponents that get returned)
Return Values
analytics: data for the given key resolved byfetcher(or undefined if not loaded)Capture: data for the given key resolved byfetcher(or undefined if not loaded)PageView: error thrown byfetcher(or undefined)
PageView
function Page() {
const { PageView } = useMetrics({
variantId,
// ...properties to capture
}, { ready: variantId !== undefined })
return (
<PageView
name="Home"
category="Customer"
ready={/* some useState value perhaps */ }
>
// ...
</PageView>
)
}This will call analytics.page() when it is rendered (in a useEffect). Note the use of the ready option in useMetrics as well as on the PageView component. This will defer the page event until all "captured" ready properties are true. In this case, it will wait until variantId is loaded (asyncronously perhaps).
PageView is also similar to the Capture component in that it captures all properties in context to be used deeper in the (virtual) DOM tree.
properties
ready:booleanto defer any PageView events until all appropriate properties have been determined. (See note below)#about-ready
Capture
function Card({ productId }) {
const { Capture } = useMetrics({
productId,
// ...properties to capture
})
return (
<Capture ready={/* (optional) */}>
// ...
</Capture>
)
}This will capture all the properties provided to useMetrics and pass them via context to any nested calls to useMetrics.
properties
ready:booleanto defer any PageView events until all appropriate properties have been determined.
About ready
NOTE: The
readyprop used on theCapturecomponent will only apply to any nestedPageViewcomponents. ThePageViewcomponent will only callanalytics.page()when thereadyprop onPageView(itself) and all capturedreadyvalues above it in the virtual DOM are true.
analytics
This object has the same implementation as the analytics object you passed to MetricsProvider(#Mount MetricsProvider).
analytics.track(name, properties)
function Card({ productId }) {
const { analytics } = useMetrics({
// ...properties to capture
})
return (
<button
onClick={() => analytics.track('Button clicked', {
// ...additional properties to bubble up
})}
>
// ...
</button>
)
}Use the analytics object to imperatively send a tracking event (page() works also). Any properties you pass will be merged with those that have been "captured" higher in the virtual DOM.
analytics.page(name, properties, category)
function LandingPage() {
const { analytics } = useMetrics({
// ...properties to capture
})
useEffect(() => {
analytics.page('Landing page', { /* ...other properties */ }, 'Category')
}, [])
}Contributing
- Use conventional commits
- Run
yarn testandyarn lint npm version patch/minor/majornpm publish- Then push to git remote
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago