user-events v0.0.6
Analytics
A pluggable analytics library designed to work with any third party analytics tool.
Connect with your favorite analytic providers, trigger custom logic based on user activity, or easily provide opt out mechanisms for visitors who wish to turn off analytics entirely.
Table of Contents
- Features
- Why
- Philosophy
- Install
- Usage
- Demo
- API
- analytics.identify
- analytics.track
- analytics.page
- analytics.getState
- analytics.reset
- analytics.dispatch
- analytics.storage
- analytics.storage.getItem
- analytics.storage.setItem
- analytics.storage.removeItem
- analytics.user
- analytics.ready
- analytics.on
- analytics.once
- analytics.enablePlugin
- analytics.disablePlugin
- analytics.loadPlugin
- analytics.events
- Analytic plugins
- Creating analytics plugins
- Plugin Naming Conventions
- CONTRIBUTING
Features
- Pluggable - Bring your own third party tool
- Works on client & server-side
- Test & Debug analytics integrations with time travel & offline mode.
- (WIP) In client, works offline. Queues events to send when connection resumes
Why
Companies frequently change analytics & collection requirements. This results in adding & removing analytic services a painful time consuming process.
This library aims to solves that with a simple abstraction layer.
Philosophy
You should never be locked into a tool.
To add or remove an analytics provider adjust the plugins
you load into analytics
.
Install
npm install analytics --save
Usage
import Analytics from 'analytics'
import googleAnalyticsPlugin from 'analytics-plugin-ga'
import customerIOPlugin from 'analytics-plugin-customerio'
const analytics = Analytics({
app: 'my-app-name',
version: 100,
plugins: [
googleAnalyticsPlugin({
trackingId: 'UA-121991291',
}),
customerIOPlugin({
siteId: '123-xyz'
})
]
})
// Fire a page view
analytics.page()
// Fire event tracking
analytics.track('userPurchase', {
price: 20
})
// Identify a visitor
analytics.identify('user-id-xyz', {
firstName: 'bill',
lastName: 'murray',
email: 'da-coolest@aol.com'
})
//...
Demo
See Analytics Demo for a site example.
API
analytics.identify
Identify a user. This will trigger identify
calls in any installed plugins and will set user data in localStorage
Arguments
- userId String - Unique ID of user
- traits Object - Object of user traits
- options Object - Options to pass to indentify call
- callback Function - Optional callback function after identify completes
Example
identify('xyz-123', {
name: 'steve',
company: 'hello-clicky'
})
analytics.track
Track an analytics event. This will trigger track
calls in any installed plugins
Arguments
- eventName String - Event name
- payload Object - Event payload
- options Object - Event options
- callback Function - Callback to fire after tracking completes
Example
analytics.track('buttonClick')
analytics.page
Trigger page view. This will trigger page
calls in any installed plugins
Arguments
- data String - (optional) page data
- options Object - Event options
- callback Function - Callback to fire after page view call completes
Example
analytics.page()
analytics.getState
Get data about user, activity, or context. You can access sub-keys of state with dot.prop
syntax.
Arguments
- key String - (optional) dotprop sub value of state
Example
// Get the current state of analytics
analytics.getState()
// Get a subpath of state
analytics.getState('context.offline')
analytics.reset
Clear all information about the visitor & reset analytic state.
Arguments
- callback Function - Handler to run after reset
analytics.dispatch
Emit events for other plugins or middleware to react to.
Arguments
- action Object description
analytics.storage
Storage utilities for persisting data. These methods will allow you to save data in localStorage, cookies, or to the window.
analytics.storage.getItem
Get value from storage
Arguments
- key String - storage key
- options Object - storage options
Example
analytics.storage.getItem('storage_key')
analytics.storage.setItem
Set storage value
Arguments
- key String - storage key
- value Any - storage value
- options Object - storage options
Example
analytics.storage.setItem('storage_key', 'value')
analytics.storage.removeItem
Remove storage value
Arguments
- key String - storage key
- options Object - storage options
Example
analytics.storage.removeItem('storage_key')
analytics.user
Get user data
Arguments
- key String - dot.prop subpath of user data
Example
// get all user data
const userData = analytics.user()
// get user company name
const companyName = analytics.user('company.name')
analytics.ready
Fire callback on analytics ready event
Arguments
- callback Function - function to trigger when all providers have loaded
Example
analytics.ready((action, instance) => {
console.log('all plugins have loaded')
})
analytics.on
Attach an event handler function for one or more events to the selected elements.
Arguments
- name String - Name of event to listen to
- callback Function - function to fire on event
Example
analytics.on('track', ({ action, instance }) => {
console.log('track call just happened. Do stuff')
})
analytics.once
Attach a handler function to an event and only trigger it only once.
Arguments
- name String - Name of event to listen to
- callback Function - function to fire on event
Example
analytics.once('track', (action, instance) => {
console.log('This will only triggered once')
})
analytics.enablePlugin
Enable analytics plugin
Arguments
- name String|Array - name of integration(s) to disable
- callback Function - callback after enable runs
Example
analytics.enablePlugin('google')
// enable multiple plugins at once
analytics.enablePlugin(['google', 'segment'])
analytics.disablePlugin
Disable analytics plugin
Arguments
- name string|array - name of integration(s) to disable
- callback Function - callback after disable runs
Example
analytics.disablePlugin('google')
analytics.disablePlugin(['google', 'segment'])
analytics.loadPlugin
Load registered analytic providers.
Arguments
- namespace String - integration namespace
Example
analytics.loadPlugin('segment')
analytics.events
Events exposed by core analytics library and all loaded plugins
Analytic plugins
The analytics
has a robust plugin system. Here is a list of currently available plugins:
- analytics-plugin-customerio Customer.io plugin for 'analytics' npm link.
- analytics-plugin-do-not-track Disable tracking for opted out visitors npm link.
- analytics-plugin-ga Google analytics integration for 'analytics' pkg npm link.
- analytics-plugin-google-tag-manager Google tag manager plugin for 'analytics' pkg npm link.
- analytics-plugin-lifecycle-example Example plugin with lifecycle methods npm link.
- analytics-plugin-original-source Save original referral source of visitor npm link.
- analytics-plugin-segment Segment integration for 'analytics' pkg npm link.
- analytics-plugin-tab-events Expose tab visibility events for analytics npm link.
- analytics-plugin-window-events Expose window events for analytics npm link.
- analytics-utils Analytics utility functions npm link.
- Add yours! 👇
Creating analytics plugins
The library is designed to work with any third party analytics tool.
Plugins are just plain javascript objects that expose methods for analytics
core to register and call.
Here is a quick example of a plugin. This is a 'vanilla' plugin example for connecting a third party analytics tool
// vanilla-example.js
export default function googleAnalytics(userConfig) {
// return object for analytics to use
return {
// All plugins require a namespace
NAMESPACE: 'google-analytics',
config: {
whatEver: userConfig.fooBar,
googleAnalyticsId: userConfig.id
},
initialize: ({ config }) => {
// load provider script to page
},
page: ({ payload }) => {
// call provider specific page tracking
},
track: ({ payload }) => {
// call provider specific event tracking
},
identify: ({ payload }) => {
// call provider specific user identify method
},
loaded: () => {
// return boolean so analytics knows when it can send data to third party
return !!window.gaplugins
}
}
}
To use a plugin, import it and pass it into the plugins
array when you bootstrap analytics
.
import Analytics from 'analytics'
import vanillaExample from './vanilla-example.js'
const analytics = Analytics({
app: 'my-app-name',
plugins: [
vanillaExample({ id: 'xyz-123' }),
...otherPlugins
]
})
React to any event
Plugins can react to any event flowing through analytics
.
For example, if you wanted to trigger custom logic when analytics
bootstraps you can attach a function handler to the bootstrap
event.
For a full list of core events, checkout events.js
.
// plugin.js
export default function myPlugin(userConfig) {
return {
NAMESPACE: 'my-plugin',
bootstrap: ({ payload, config, instance }) => {
// Do whatever on `bootstrap`
},
pageStart: ({ payload, config, instance }) => {
// Fire custom logic before .page calls
},
pageEnd: ({ payload, config, instance }) => {
// Fire custom logic after .page calls
},
trackStart: ({ payload, config, instance }) => {
// Fire custom logic before .track calls
},
'track:customerio': ({ payload, config, instance }) => {
// Fire custom logic before customer.io plugin runs.
// Here you can customize the data sent to individual analytics providers
},
trackEnd: ({ payload, config, instance }) => {
// Fire custom logic after .track calls
},
...
}
}
Using this plugin is the same as any other.
import Analytics from 'analytics'
import customerIoPlugin from 'analytics-plugin-customerio'
import myPlugin from './plugin.js'
const analytics = Analytics({
app: 'my-app-name',
plugins: [
myPlugin(),
customerIoPlugin({
trackingId: '1234'
})
...otherPlugins
]
})
(optionally) Use middleware
Alternatively, you can also add whatever middleware functionality you'd like from the redux
ecosystem.
// logger-plugin.js redux middleware
const logger = store => next => action => {
if (action.type) {
console.log(`>> dispatching ${action.type}`, JSON.stringify(action))
}
let result = next(action)
return result
}
export default logger
Using this plugin is the same as any other.
import Analytics from 'analytics'
import loggerPlugin from './logger-plugin.js'
const analytics = Analytics({
app: 'my-app-name',
plugins: [
...otherPlugins,
loggerPlugin
]
})
Opt out example plugin
This is a vanilla redux middleware that will opt out users from tracking. There are many ways to implement this type of functionality using analytics
const optOutMiddleware = store => next => action => {
const { type } = action
if (type === 'trackStart' || type === 'pageStart' || type === 'trackStart') {
// Check cookie/localStorage/Whatever to see if visitor opts out
// Here I am checking user traits persisted to localStorage
const { user } = store.getState()
// user has optOut trait cancel action
if (user && user.traits.optOut) {
return next({
...action,
...{
abort: true,
reason: 'User opted out'
},
})
}
}
return next(finalAction)
}
export default optOutMiddleware
Plugin Naming Conventions
Plugins should follow a naming convention before being published to NPM
analytics-plugin-{your-plugin-name}
npm install analytics-plugin-awesome-thing
CONTRIBUTING
Contributions are always welcome, no matter how large or small. Before contributing, please read the code of conduct.