
react-tracker

Track user interaction with React based apps
What?
- React specific tracking library, usable as a higher-order component
- Flexible-scalable solution for tracking
- Can be pluged with any Analytics platform :
- Google Tag Manager
- Facebook Pixel
- You can mainly do anything in the event listeners callback..
- Easy to use (Redux-like)
Installation
$ npm install --save react-tracker
This assumes you are using npm as your package manager.
Demo
To see the react-tracker in action please visit the link below.
Link
Documentation
Initialize the Tracker
Create a Tracker holding the tracked events History of your app.
Tracker API is { on, trackEvent, getHistory }.
- You can pass your already defined event listeners to the constructor like so:
const tracker = new Tracker([trackAddToCart])
- Or you can listen-on-the-go using
on():
const tracker = new Tracker();
tracker.on('PRODUCT_CLICK', (event, eventsHistory) =>
console.log(event)
);
tracker.on('*', (event, eventsHistory) =>
console.log(event)
);
Create Event listener
Event listner is a pure function with (event, eventsHistory) => tracking goes here.
It describes what to do with the just-fired event.
Why providing the eventsHistory as second parameter ?
=> because in some cases you'll need to apply some restrictions on some events E.g:
- Track product click only once!
- Track product click only if pageView is already tracked
- etc
Listen on one event
function trackAddToCart(event, eventsHistory) {
window.dataLayer.push(...event.data);
return event
}
trackAddToCart.eventType = 'ADD_TO_CART';
Listen on all events
function trackCartEvents(event, eventsHistory) {
switch(event.type) {
case 'ADD_TO_CART':
window.dataLayer.push(...event);
break;
default:
}
}
Track Events
trackEvent is a function that accept an object describes the event as argument.
- Track event
ADD_TO_CART_EVENT with data.
tracker.trackEvent({
type: 'ADD_TO_CART_EVENT',
data: {
productId: '12345',
quantity: 5
}
})
- Track event
PRODUCT_CLICK with no associated data.
tracker.trackEvent({ type: 'PRODUCT_CLICK' })
Usage with React
Provide tracker to the root component
All container components need access to the tracker so they can track events.
We will use the <TrackerProvider> to magically make the tracker available to all container components in the application without passing it explicitly.
You only need to use it once when you render the root component:
index.js
import React from 'react'
import { render } from 'react-dom'
import { TrackerProvider, Tracker } from 'react-tracker'
import { trackProductClick } from './tracking/listeners/cart'
import ProductsList from './components/ProductsList'
const tracker = new Tracker([trackProductClick])
render(
<TrackerProvider tracker={tracker}>
<ProductsList products={someProducts} />
</TrackerProvider>,
document.getElementById('root')
)
Create Add to Cart Event Listener .../tracking/listeners/cart.js
function trackAddToCart(event, eventsHistory) {
window.dataLayer.push(...event);
return event
}
trackAddToCart.eventType = 'ADD_TO_CART';
export default trackAddToCart;
Add To Cart Event creator .../tracking/events/cart.js
Event creator should return an object that describe the event (Type and data).
- type: string (Required)
- data: Any (Optional)
function getAddToCartEvent(id, price) {
return {
type: 'ADD_TO_CART',
data: {
id: id,
price: price
}
}
};
Create Product Component components/Product.js
import React from 'react'
const Product = ({ onClick, title, price, currency }) => (
<li
onClick={onClick}
>
{title}
<span> {price} {currency} </span>
</li>
)
export default Product
Create Products List Component components/ProductList.js
import Product from './Product'
const ProductList = ({ products, trackAddToCart }) => (
<ul>
{products.map(product => (
<Product key={product.id} {...product} onClick={() => trackAddToCart(product.id, product.price)} />
))}
</ul>
)
ProductList.propTypes = {
trackAddToCart: PropTypes.func
}
export default ProductList
Create mapTrackingToProps function and pass it to withTracking HOC .../compoenets/ProductListContainer.js
mapTrackingToProps should return an object which will be merged with the component Props.
import React from 'react';
import { withTracking } from 'react-tracker';
import { getAddToCartEvent } from '.../tracking/events/cart';
import ProductsList from './ProductsList';
const mapTrackingToProps = trackEvent => {
return {
trackAddToCart: (id, price) => {
trackEvent(getAddToCartEvent(id, price))
}
}
}
const ProductsListWithTracking = withTracking(mapTrackingToProps)(ProductsList)
export default ProductsListWithTracking
Create redux middleware for redux-based apps
If your app is using redux for state managment, you might want to track redux actions directly.
Let's create our Redux middleware to take the tracker as argument and call trackEvent on every redux action dispatched.
const trackingMiddleware = tracker => () => next => action => {
tracker.trackEvent(action);
next(action);
};
export default trackingMiddleware;
import { createStore, applyMiddleware } from 'redux';
import { Tracker } from 'react-redux';
import { trackingMiddleware, Tracker } from '../trackingMiddleware'
const tracker = new Tracker();
const store = createStore(
reducers,
{},
applyMiddleware(trackingMiddleware(tracker))
);
Contribution
This project is in its early stages, I'd be very happy if you can help :)
License
MIT