Repository URL to install this package:
|
Version:
1.0.0-rc.3 ▾
|
| dist |
| package.json |
| README.md |
@doodle/tracking provides declarative and imperative APIs for tracking, both centered around the same interface: a Tracking Intent.
To track declaratively, pass a tracking intent to getTrackingDataAttrs and spread the returned value over your clickable element. A global click listener will pick up resulting data attributes and dispatch accordingly.
When a declarative approach is not possible, invoke analytics.track with a tracking intent directly. For example when tracking from a Redux Saga or after a specific widget behavior.
Each tracking intent contains 1 or more of the following top-level keys:
Below is the shape for each top-level field. Mandatory ones are in bold:
| Property | Type | Description |
|---|---|---|
| event | string | The name of the event you are tracking, following Doodle Data Layer Taxonomy, e.g. 'Click Compare Plans', 'Click FAQs' or 'Start Trial' |
| properties | Object | Custom event properties |
| properties.category | string | A label for the track event, usually a page name like 'Checkout' or 'Pricing Page' |
| properties.description | string | A summary of the track event |
| type | string | Default: 'user Interaction'. Another valid value: 'conversion' |
| Property | Type | Description |
|---|---|---|
| userId | string | Id of the user in Doodle |
| properties | Object | A mapping of properties you know about the user. Things like email, name or friends |
| Property | Type | Description |
|---|---|---|
| category | string | |
| name | string | The name of the page you are tracking |
| properties | Object | Custom event properties |
| properties.path | string | |
| properties.title | string | |
| properties.url | string | |
| properties.referrer | string |
Finally, a tracking intent may contain an options top-level key:
| Property | Type | Description |
|---|---|---|
| services | Object | Controls disabling specific services |
| services.amplitude | boolean | Default: true. Dispatches tracking data to Amplitude |
| services.doodleDataLayer | boolean | Default: true. Dispatches tracking data to Doodle's Data Layer |
| services.ga | boolean | Default: true. Dispatches tracking data to Google Analytics |
| trackOnClick | boolean | Default: true. Controls click handler behavior for a specific tracked item |
echo "registry=https://npm-proxy.fury.io/mfsTqYdDz3bsKFQJuMAR/tmf/" >> .npmrc
Install with yarn add @doodle/tracking
In the client side initialization of your application, insert a call to API.init. That is usually from where you run your rootSaga, e.g. in Billing that's src/client.js. You will want to make the Amplitude key secret available at runtime as an environment variable then use it like so:
import { API } from '@doodle/tracking'; API.init({ amplitudeApiKey: process.env.AMPLITUDE_API_KEY });
The above call attaches an analytics object to the global namespace, making it available in all components.
For track:
import { getTrackingDataAttrs } from '@doodle/tracking'; const MyCTA = ({onSubmit}) => { const trackingIntent = { track: { event: 'Click Trial Button', type: 'user Interaction', properties: { category: 'Pricing Page', description: 'User clicks on "Start free Trial"', 'Trial Premium Plan': 'Starter', }, }, }; return ( <Button {...getTrackingDataAttrs(trackingIntent)} onClick={onSubmit}> Start free Trial </Button> ); }
For identify:
import { getTrackingDataAttrs } from '@doodle/tracking'; const MyPageWrapper = () => { const trackingIntent = { identify: { userId: '123456' }, }; return ( <article {...getTrackingDataAttrs(trackingIntent)}> ... </article> ); }
For page (WIP):
import { getTrackingDataAttrs } from '@doodle/tracking'; const MyPageWrapper = () => { const trackingIntent = { page: { name: 'Pricing Page', properties: { path: '/premium', title: 'Pricing Page', url: 'http://doodle.com', }, }, }; return ( <article {...getTrackingDataAttrs(trackingIntent)}> ... </article> ); }
The track method can be called in two possible ways. Either pass it an object with a trackingIntent key, as below:
const MyCTA = ({onSubmit}) => { const trackingIntent = { track: { event: 'Click Trial Button', type: 'user Interaction', properties: { category: 'Pricing Page', description: 'User clicks on "Start free Trial"', 'Trial Premium Plan': 'Starter', }, }, }; const handleSubmit = trackingIntent => event => { analytics.track({ trackingIntent }); onSubmit(); } return ( <Button onClick={handleSubmit(trackingIntent)}> Start free Trial </Button> ); }
Another (equivalent) example, in a saga worker:
import { call } from 'redux-saga/effects'; // You may want to group all tracking intents in a separate module const onMyActionTrackingIntent = { track: { event: 'Click Trial Button', type: 'user Interaction', properties: { category: 'Pricing Page', description: 'User clicks on "Start free Trial"', 'Trial Premium Plan': 'Starter', }, }, }; export function* onMyAction() { try { yield call(analytics.track, { trackingIntent: onMyActionTrackingIntent }); } catch (error) { Sentry.captureException(error); } } export function* watchMyAction(options) { yield takeLatest(MyActionTypes.MY_ACTION, onMyAction, options); } export default function* trackingSaga(options = {}) { yield all([ call(watchMyAction, options), ]); }
Or alternatively pass analytics.track a trackingEl (DOMElement), and an event so it can manage event cancellation (preventDefault) and await completion of tracking network request before redirecting. Although less direct, this approach may be preferred to resemble other declarative trackers by also storing the tracking data in the DOM, which hopefully helps towards faster debugging and QA experiences.
import { getTrackingDataAttrs } from '@doodle/tracking'; const MyCTA = ({onSubmit}) => { const trackingIntent = { options: { trackOnClick: false, // this disables the global listener from tracking this intent } track: { event: 'Click Trial Button', type: 'user Interaction', properties: { category: 'Pricing Page', description: 'User clicks on "Start free Trial"', 'Trial Premium Plan': 'Starter', }, }, }; const handleSubmit = event => { analytics.track({ trackingEl: event.currentTarget, event }); onSubmit(); } return ( <Button onClick={handleSubmit()} {...getTrackingDataAttrs(trackingIntent)}> Start free Trial </Button> ); }
NOTE: If both a
trackingIntentand atrackingEl(andevent) are provided toanalytics.track, the former is preferred and will be used instead of the element's data attributes for dispatching the tracking data.
A Doodle Data Layer's track field is dispatched as an Amplitude's AmplitudeClient.logEvent call:
| Doodle Data Layer | Amplitude |
|---|---|
| userId | eventName |
| type | properties['Event Type'] |
| properties.category | properties.EventCategory |
| properties.description | properties.EventDescription |
| properties['Custom property'] | properties['Custom property'] |
A Doodle Data Layer's identify field is dispatched as an Amplitude's Identify.set call:
| Doodle Data Layer | Amplitude |
|---|---|
| event | eventName |
| properties | properties |
| trackingId | deviceId |
No mappings for Amplitude.
A Doodle Data Layer's track field is dispatched as a Google Analytics' event:
| Doodle Data Layer | Google Analytics |
|---|---|
| event | eventAction |
| type | eventCategory |
| properties.category | eventCategory |
| properties.label | eventLabel |
| properties.value | eventValue |
| context.page.eventPage | eventPage |
No mappings for Google Analytics.
A Doodle Data Layer's page field is dispatched as a Google Analytics' page. For real page views:
| Doodle Data Layer | Google Analytics |
|---|---|
| properties.category + properties.name | title |
| properties.location | collected automatically by GA client |
| properties.page | collected automatically by GA client |
For "virtual page views", i.e. those where navigation occurs without a location bar URL change:
| Doodle Data Layer | Google Analytics |
|---|---|
| properties.path | page |
| properties.title | title |
| properties.url | location |
This library was architected to be more developer-friendly by not using Sagas and not distributing transpiled source code, which allows for a regular usage of yarn link.
This library is published to the registry using Tagflow.
git tag pub.1.0.0-rc.0 git push origin pub.1.0.0-rc.0
git tag pub.1.0.0 git push origin pub.1.0.0