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.
Click to expand
- 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
- 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
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.
You should never be locked into a tool.
To add or remove an analytics provider adjust the plugins
you load into analytics
.
npm install analytics --save
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'
})
//...
See Analytics Demo for a site example.
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'
})
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')
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()
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')
Clear all information about the visitor & reset analytic state.
Arguments
- callback
Function
- Handler to run after reset
Emit events for other plugins or middleware to react to.
Arguments
- action
Object
[description]
Storage utilities for persisting data. These methods will allow you to save data in localStorage, cookies, or to the window.
Get value from storage
Arguments
- key
String
- storage key - options
Object
- storage options
Example
analytics.storage.getItem('storage_key')
Set storage value
Arguments
- key
String
- storage key - value Any - storage value
- options
Object
- storage options
Example
analytics.storage.setItem('storage_key', 'value')
Remove storage value
Arguments
- key
String
- storage key - options
Object
- storage options
Example
analytics.storage.removeItem('storage_key')
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')
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')
})
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')
})
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')
})
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'])
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'])
Load registered analytic providers.
Arguments
- namespace
String
- integration namespace
Example
analytics.loadPlugin('segment')
Events exposed by core analytics library and all loaded 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! π
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
]
})
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
]
})
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
]
})
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
Plugins should follow a naming convention before being published to NPM
analytics-plugin-{your-plugin-name}
npm install analytics-plugin-awesome-thing
Contributions are always welcome, no matter how large or small. Before contributing, please read the code of conduct.