Simple React wrapper for Components to track events.
import { createTracker } from 'react-track-events';
const trackElement = createTracker((event) => {
// Will be called each time a tracked event is fired with:
// {
// eventName: event like 'onClick',
// ComponentType: something like `Dropdown`,
// info?: 'whatever you passed to the trackEvent attribute (or return value of it being a function)'
// breadcrumbs: array of <Breadcrumb> crumbs wrapping the node
// args: [nativeEvent, ...args] // args passed to the event handler,
// returnValue?: Whatever the event handler returned
// thisContext?: context the event handler was called with;
// }
});
// Create a simple tracker for a div
const Div = trackElement.trackIntrinsicElement('div');
const trackedDiv = <Div trackClick>I'm being tracked</Div>;
// OR use the returned intrinsicElements object
const tracked = trackElement.intrinsicElements;
const trackedDiv = <tracked.div trackClick>I'm being tracked</tracked.div>;
const untrackedDiv = <Div>I'm not because there's no trackClick attribute</Div>;
const ClickTrackedDiv = trackElement.trackIntrinsicElement('div', {
alwaysTrack: ['onClick'],
});
// OR
const ClickTrackedDiv = trackElement.withOptions({
alwaysTrack: ['onClick'],
}).div;
const clickTrackedDiv = <ClickTrackedDiv>I'm being tracked</ClickTrackedDiv>;
const autoTrackedDivWithFocus = (
<ClickTrackedDiv trackFocus>
I'm being tracked for clicks and focus
</ClickTrackedDiv>
);
const noClickTrackedDiv = (
<ClickTrackedDiv trackClick={false}>Not tracked</ClickTrackedDiv>
);
// You can pass trackClick a value that will be passed to the tracker as the info property
// event.info will be "some info"
const trackedDivWithInfo = <Div trackClick="some info">I'm being tracked</Div>;
// event.info will be `{ foo: 123 }`
const trackedDivWithComplexInfo = <Div trackClick={{ foo: 123 }}>tracked</Div>;
// You can also pass a function will will then pass the return value as the info property
// In this case event.info will be "my-class"
const trackedDivWithFn = (
<Div className="my-class" trackClick={(e) => e.target.className}>
Tracked with function
</Div>
);
// You can track any React element, for example a Material UI Checkbox
const AutoTrackedCheckbox = trackElement(Checkbox, {
alwaysTrack: ['onChange'],
});
const autoTrackedCheckbox = <AutoTrackedCheckbox />;
const TrackedCheckbox = trackElement(Checkbox);
// The function can pass important info about the event to the onEvent handler
const box = (
<TrackedCheckbox trackChange={(event, value) => `checkbox-${value}`} />
);
// The above will pass 'checkbox-true' or 'checkbox-false' to the onEvent handler
Beside the original typings of the tracked element (eg form
having onSubmit
, and Checkbox
having onChange
) you can also supply a generic type to createTracker
to specify the type of the info
property of the event and what should be passed in the trackFoo
props.
const trackStringyElement = createTracker<string>((event) => {
// event.info will be a string
});
const Div = trackStringyElement.intrinsicElements.div;
const trackedDivGood = <Div trackClick="some info">I'm being tracked</Div>; // OK
const trackedDivBad1 = <Div>trackClick is required</Div>; // Type Error
const trackedDivBad2 = <Div trackClick>trackClick needs to be a string</Div>; // Type Error
const trackComplexElement = createTracker<
string | { feature: string; attributes: any }
>((event) => {
const isString = typeof event.info === 'string';
const info = isString ? { feature: event.info } : event.info;
// analytics.track(info);
});
const D2 = trackStringyElement.intrinsicElements('div');
const trackedDiv1 = <D2 trackClick="foo" />; // OK
const trackedDiv2 = <D2 trackClick={{ feature: 'bar', attributes: 123 }} />; // OK
const trackedDiv3 = <D2 trackClick={{ attributes: 123 }} />; // Type Error
In the examples above the breadcrumbs property will be an empty array since no <Breadcrumbs />
were provided. You can wrap any parent component with <Breadcrumbs />
to provide a list of breadcrumbs to the event handler. This can be used to know which section of a page a Checkbox was toggled or a link was clicked. For example:
const App = () => {
return (
<>
<Breadcrumb name="header">
<Header />
</Breadcrumb>
<Breadcrumb name="layout">
<Layout />
</Breadcrumb>
</>
);
};
const Layout = () => {
return (
<div>
<Breadcrumb crumb="section1">
<Section1 />
</Breadcrumb>
<Breadcrumb crumb="section2">
<Section2 />
</Breadcrumb>
<Breadcrumb crumb="section3">
<Section3 />
</Breadcrumb>
</div>
);
};
const Section2 = () => <tracked.div trackClick>Tracked</tracked.div>;
The tracked.div
will have ['layout', 'section2']
as the breadcrumb value.