Analytics

Lightweight analytics abstraction layer for tracking page views, custom eve...

README


npm npm bundle size GitHub

A lightweight analytics abstraction library for tracking page views, custom events, & identify visitors.

Designed to work with any third-party analytics tool or your own backend.


Table of Contents


Click to expand

- Why
- API


Features


- [x] Extendable - Bring your own third-party tool & plugins
- [x] Test & debug analytics integrations with time travel & offline mode
- [x] Add functionality/modify tracking calls with baked in lifecycle hooks
- [x] Isomorphic. Works in browser & on server
- [x] Queues events to send when analytic libraries are loaded
- [x] Conditionally load third party scripts
- [x] Works offline

Why


Companies frequently change analytics requirements based on evolving needs. This results in a lot of complexity, maintenance, & extra code when adding/removing analytic services to a site or application.

This library aims to solves that with a simple pluggable abstraction layer.

how analytics works

Driving philosophy:

- You should never be locked into an analytics tool
- DX is paramount. Adding & removing analytic tools from your application should be easy
- Respecting visitor privacy settings & allowing for opt-out mechanisms is crucial
- A pluggable API makes adding new business requests easy

To add or remove an analytics provider, adjust the plugins you load into analytics during initialization.

Install


This module is distributed via npm, which is bundled with node and should be installed as one of your project's dependencies.

  1. ``` sh
  2. npm install analytics --save
  3. ```

Or as a script tag:

  1. ``` html
  2. <script src="https://unpkg.com/analytics/dist/analytics.min.js"></script>
  3. ```

Usage


  1. ``` js
  2. import Analytics from 'analytics'
  3. import googleAnalytics from '@analytics/google-analytics'
  4. import customerIo from '@analytics/customerio'

  5. /* Initialize analytics */
  6. const analytics = Analytics({
  7.   app: 'my-app-name',
  8.   version: 100,
  9.   plugins: [
  10.     googleAnalytics({
  11.       trackingId: 'UA-121991291',
  12.     }),
  13.     customerIo({
  14.       siteId: '123-xyz'
  15.     })
  16.   ]
  17. })

  18. /* Track a page view */
  19. analytics.page()

  20. /* Track a custom event */
  21. analytics.track('userPurchase', {
  22.   price: 20,
  23.   item: 'pink socks'
  24. })

  25. /* Identify a visitor */
  26. analytics.identify('user-id-xyz', {
  27.   firstName: 'bill',
  28.   lastName: 'murray',
  29.   email: 'da-coolest@aol.com'
  30. })
  31. ```

Node.js usage

  For ES6/7 javascript you can import Analytics from 'analytics' for normal node.js usage you can import like so:

  1. ``` js
  2.   const { Analytics } = require('analytics')
  3.   // or const Analytics = require('analytics').default
  4.   const googleAnalytics = require('@analytics/google-analytics')
  5.   const customerIo = require('@analytics/customerio')

  6.   const analytics = Analytics({
  7.     app: 'my-app-name',
  8.     version: 100,
  9.     plugins: [
  10.       googleAnalytics({
  11.         trackingId: 'UA-121991291',
  12.       }),
  13.       customerIo({
  14.         siteId: '123-xyz'
  15.       })
  16.     ]
  17.   })

  18.   /* Track a page view */
  19.   analytics.page()

  20.   /* Track a custom event */
  21.   analytics.track('userPurchase', {
  22.     price: 20,
  23.     item: 'pink socks'
  24.   })

  25.   /* Identify a visitor */
  26.   analytics.identify('user-id-xyz', {
  27.     firstName: 'bill',
  28.     lastName: 'murray',
  29.     email: 'da-coolest@aol.com'
  30.   })
  31. ```

Browser usage

  When importing global analytics into your project from a CDN, the library exposes via a global _analytics variable.

  Call _analytics.init to create an analytics instance.

  1. ``` html
  2.   <script src="https://unpkg.com/analytics/dist/analytics.min.js"></script>
  3.   <script>
  4.     const Analytics = _analytics.init({
  5.       app: 'my-app-name',
  6.       version: 100,
  7.       plugins: []
  8.     })
  9.     /* Track a page view */
  10.     Analytics.page()
  11.     /* Track a custom event */
  12.     Analytics.track('userPurchase', {
  13.       price: 20,
  14.       item: 'pink socks'
  15.     })
  16.     /* Identify a visitor */
  17.     Analytics.identify('user-id-xyz', {
  18.       firstName: 'bill',
  19.       lastName: 'murray',
  20.       email: 'da-coolest@aol.com'
  21.     })
  22.   </script>
  23. ```


Demo


See Analytics Demo for a site example.

API


The core analytics API is exposed once the library is initialized with configuration.

Typical usage:

1. Initialize with configuration
2. Export the analytics instance with third-party providers (Google Analytics, HubSpot, etc)
3. Use [page](#analyticspage), [identify](#analyticsidentify), [track](#analyticstrack) in your app

Configuration


Analytics library configuration

After the library is initialized with config, the core API is exposed & ready for use in the application.

Arguments

- **config** object - analytics core config- **[config.app]** (optional) string - Name of site / app- **[config.version]** (optional) string - Version of your app- **[config.debug]** (optional) boolean - Should analytics run in debug mode- **[config.plugins]** (optional) Array.<AnalyticsPlugin> - Array of analytics plugins

Example

  1. ``` js
  2. import Analytics from 'analytics'
  3. import pluginABC from 'analytics-plugin-abc'
  4. import pluginXYZ from 'analytics-plugin-xyz'

  5. // initialize analytics
  6. const analytics = Analytics({
  7.   app: 'my-awesome-app',
  8.   plugins: [
  9.     pluginABC,
  10.     pluginXYZ
  11.   ]
  12. })
  13. ```

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]** (optional) Object - Object of user traits- **[options]** (optional) Object - Options to pass to identify call- **[callback]** (optional) Function - Callback function after identify completes

Example

  1. ``` js
  2. // Basic user id identify
  3. analytics.identify('xyz-123')

  4. // Identify with additional traits
  5. analytics.identify('xyz-123', {
  6.   name: 'steve',
  7.   company: 'hello-clicky'
  8. })

  9. // Fire callback with 2nd or 3rd argument
  10. analytics.identify('xyz-123', () => {
  11.   console.log('do this after identify')
  12. })

  13. // Disable sending user data to specific analytic tools
  14. analytics.identify('xyz-123', {}, {
  15.   plugins: {
  16.     // disable sending this identify call to segment
  17.     segment: false
  18.   }
  19. })

  20. // Send user data to only to specific analytic tools
  21. analytics.identify('xyz-123', {}, {
  22.   plugins: {
  23.     // disable this specific identify in all plugins except customerio
  24.     all: false,
  25.     customerio: true
  26.   }
  27. })
  28. ```

analytics.track


Track an analytics event. This will trigger track calls in any installed plugins

Arguments

- **eventName** String - Event name- **[payload]** (optional) Object - Event payload- **[options]** (optional) Object - Event options- **[callback]** (optional) Function - Callback to fire after tracking completes

Example

  1. ``` js
  2. // Basic event tracking
  3. analytics.track('buttonClicked')

  4. // Event tracking with payload
  5. analytics.track('itemPurchased', {
  6.   price: 11,
  7.   sku: '1234'
  8. })

  9. // Fire callback with 2nd or 3rd argument
  10. analytics.track('newsletterSubscribed', () => {
  11.   console.log('do this after track')
  12. })

  13. // Disable sending this event to specific analytic tools
  14. analytics.track('cartAbandoned', {
  15.   items: ['xyz', 'abc']
  16. }, {
  17.   plugins: {
  18.     // disable track event for segment
  19.     segment: false
  20.   }
  21. })

  22. // Send event to only to specific analytic tools
  23. analytics.track('customerIoOnlyEventExample', {
  24.   price: 11,
  25.   sku: '1234'
  26. }, {
  27.   plugins: {
  28.     // disable this specific track call all plugins except customerio
  29.     all: false,
  30.     customerio: true
  31.   }
  32. })
  33. ```

analytics.page


Trigger page view. This will trigger page calls in any installed plugins

Arguments

- **[data]** (optional) PageData - Page data overrides.- **[options]** (optional) Object - Page tracking options- **[callback]** (optional) Function - Callback to fire after page view call completes

Example

  1. ``` js
  2. // Basic page tracking
  3. analytics.page()

  4. // Page tracking with page data overrides
  5. analytics.page({
  6.   url: 'https://google.com'
  7. })

  8. // Fire callback with 1st, 2nd or 3rd argument
  9. analytics.page(() => {
  10.   console.log('do this after page')
  11. })

  12. // Disable sending this pageview to specific analytic tools
  13. analytics.page({}, {
  14.   plugins: {
  15.     // disable page tracking event for segment
  16.     segment: false
  17.   }
  18. })

  19. // Send pageview to only to specific analytic tools
  20. analytics.page({}, {
  21.   plugins: {
  22.     // disable this specific page in all plugins except customerio
  23.     all: false,
  24.     customerio: true
  25.   }
  26. })
  27. ```

analytics.user


Get user data

Arguments

- **[key]** (optional) string - dot.prop.path of user data. Example: 'traits.company.name'

Example

  1. ``` js
  2. // Get all user data
  3. const userData = analytics.user()

  4. // Get user id
  5. const userId = analytics.user('userId')

  6. // Get user company name
  7. const companyName = analytics.user('traits.company.name')
  8. ```

analytics.reset


Clear all information about the visitor & reset analytic state.

Arguments

- **[callback]** (optional) Function - Handler to run after reset

Example

  1. ``` js
  2. // Reset current visitor
  3. analytics.reset()
  4. ```

analytics.ready


Fire callback on analytics ready event

Arguments

- **callback** Function - function to trigger when all providers have loaded

Example

  1. ``` js
  2. analytics.ready((payload) => {
  3.   console.log('all plugins have loaded or were skipped', payload);
  4. })
  5. ```

analytics.on


Attach an event handler function for analytics lifecycle events.

Arguments

- **name** String - Name of event to listen to- **callback** Function - function to fire on event

Example

  1. ``` js
  2. // Fire function when 'track' calls happen
  3. analytics.on('track', ({ payload }) => {
  4.   console.log('track call just happened. Do stuff')
  5. })

  6. // Remove listener before it is called
  7. const removeListener = analytics.on('track', ({ payload }) => {
  8.   console.log('This will never get called')
  9. })

  10. // cleanup .on listener
  11. removeListener()
  12. ```

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

  1. ``` js
  2. // Fire function only once 'track'
  3. analytics.once('track', ({ payload }) => {
  4.   console.log('This will only triggered once when analytics.track() fires')
  5. })

  6. // Remove listener before it is called
  7. const listener = analytics.once('track', ({ payload }) => {
  8.   console.log('This will never get called b/c listener() is called')
  9. })

  10. // cleanup .once listener before it fires
  11. listener()
  12. ```

analytics.getState


Get data about user, activity, or context. Access sub-keys of state with dot.prop syntax.

Arguments

- **[key]** (optional) string - dot.prop.path value of state

Example

  1. ``` js
  2. // Get the current state of analytics
  3. analytics.getState()

  4. // Get a subpath of state
  5. analytics.getState('context.offline')
  6. ```

analytics.storage


Storage utilities for persisting data.
These methods will allow you to save data in localStorage, cookies, or to the window.

Example

  1. ``` js
  2. // Pull storage off analytics instance
  3. const { storage } = analytics

  4. // Get value
  5. storage.getItem('storage_key')

  6. // Set value
  7. storage.setItem('storage_key', 'value')

  8. // Remove value
  9. storage.removeItem('storage_key')
  10. ```

analytics.storage.getItem


Get value from storage

Arguments

- **key** String - storage key- **[options]** (optional) Object - storage options

Example

  1. ``` js
  2. analytics.storage.getItem('storage_key')
  3. ```

analytics.storage.setItem


Set storage value

Arguments

- **key** String - storage key- **value** any - storage value- **[options]** (optional) Object - storage options

Example

  1. ``` js
  2. analytics.storage.setItem('storage_key', 'value')
  3. ```

analytics.storage.removeItem


Remove storage value

Arguments

- **key** String - storage key- **[options]** (optional) Object - storage options

Example

  1. ``` js
  2. analytics.storage.removeItem('storage_key')
  3. ```

analytics.plugins


Async Management methods for plugins.

This is also where custom methods are loaded into the instance.

Example

  1. ``` js
  2. // Enable a plugin by namespace
  3. analytics.plugins.enable('keenio')

  4. // Disable a plugin by namespace
  5. analytics.plugins.disable('google-analytics')
  6. ```

analytics.plugins.enable


Enable analytics plugin

Arguments

- **plugins** string|Array.<string> - name of plugins(s) to disable- **[callback]** (optional) Function - callback after enable runs

Example

  1. ``` js
  2. analytics.plugins.enable('google-analytics').then(() => {
  3.   console.log('do stuff')
  4. })

  5. // Enable multiple plugins at once
  6. analytics.plugins.enable(['google-analytics', 'segment']).then(() => {
  7.   console.log('do stuff')
  8. })
  9. ```

analytics.plugins.disable


Disable analytics plugin

Arguments

- **plugins** string|Array.<string> - name of integration(s) to disable- **callback** Function - callback after disable runs

Example

  1. ``` js
  2. analytics.plugins.disable('google').then(() => {
  3.   console.log('do stuff')
  4. })

  5. analytics.plugins.disable(['google', 'segment']).then(() => {
  6.   console.log('do stuff')
  7. })
  8. ```

Events


The analytics library comes with a large variety of event listeners that can be used to fire custom functionality when a specific lifecycle event occurs.

These listeners can be fired using analytics.on & analytics.once

  1. ``` js
  2. const eventName = 'pageEnd'
  3. analytics.on(eventName, ({ payload }) => {
  4.   console.log('payload', payload)
  5. })
  6. ```

Below is a list of the current available events

| Event | Description |
|:------|:-------|
| **`bootstrap`** | Fires when analytics library starts up.
This is the first event fired. '.on/once' listeners are not allowed on bootstrap
Plugins can attach logic to this event |
| params | Fires when analytics parses URL parameters |
| campaign | Fires if params contain "utm" parameters |
| initializeStart | Fires before 'initialize', allows for plugins to cancel loading of other plugins |
| initialize | Fires when analytics loads plugins |
| initializeEnd | Fires after initialize, allows for plugins to run logic after initialization methods run |
| ready | Fires when all analytic providers are fully loaded. This waits for 'initialize' and 'loaded' to return true |
| **`resetStart`** | Fires if analytic.reset() is called.
Use this event to cancel reset based on a specific condition || **`reset`** | Fires if analytic.reset() is called.
Use this event to run custom cleanup logic (if needed) || **`resetEnd`** | Fires after analytic.reset() is called.
Use this event to run a callback after user data is reset || **`pageStart`** | Fires before 'page' events fire.
This allows for dynamic page view cancellation based on current state of user or options passed in. || **`page`** | Core analytics hook for page views.
If your plugin or integration tracks page views, this is the event to fire on. |
| pageEnd | Fires after all registered 'page' methods fire. |
| pageAborted | Fires if 'page' call is cancelled by a plugin |
| **`trackStart`** | Called before the 'track' events fires.
This allows for dynamic page view cancellation based on current state of user or options passed in. || **`track`** | Core analytics hook for event tracking.
If your plugin or integration tracks custom events, this is the event to fire on. |
| trackEnd | Fires after all registered 'track' events fire from plugins. |
| trackAborted | Fires if 'track' call is cancelled by a plugin |
| **`identifyStart`** | Called before the 'identify' events fires.
This allows for dynamic page view cancellation based on current state of user or options passed in. || **`identify`** | Core analytics hook for user identification.
If your plugin or integration identifies users or user traits, this is the event to fire on. |
| identifyEnd | Fires after all registered 'identify' events fire from plugins. |
| identifyAborted | Fires if 'track' call is cancelled by a plugin |
| userIdChanged | Fires when a user id is updated |
| registerPlugins | Fires when analytics is registering plugins |
| enablePlugin | Fires when 'analytics.plugins.enable()' is called |
| disablePlugin | Fires when 'analytics.plugins.disable()' is called |
| **`online`** | Fires when browser network goes online.
This fires only when coming back online from an offline state. |
| offline | Fires when browser network goes offline. |
| **`setItemStart`** | Fires when analytics.storage.setItem is initialized.
This event gives plugins the ability to intercept keys & values and alter them before they are persisted. || **`setItem`** | Fires when analytics.storage.setItem is called.
This event gives plugins the ability to intercept keys & values and alter them before they are persisted. |
| setItemEnd | Fires when setItem storage is complete. |
| setItemAborted | Fires when setItem storage is cancelled by a plugin. |
| **`removeItemStart`** | Fires when analytics.storage.removeItem is initialized.
This event gives plugins the ability to intercept removeItem calls and abort / alter them. || **`removeItem`** | Fires when analytics.storage.removeItem is called.
This event gives plugins the ability to intercept removeItem calls and abort / alter them. |
| removeItemEnd | Fires when removeItem storage is complete. |
| removeItemAborted | Fires when removeItem storage is cancelled by a plugin. |

Analytic plugins


The analytics has a robust plugin system. Here is a list of currently available plugins:

| Plugin | Stats | Version |
|:---------------------------|:---------------:|:-----------:|
| **[@analytics/activity-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-activity)**
User activity listener utilities | | **0.1.13** || **[@analytics/amplitude](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-amplitude)**
Amplitude integration for 'analytics' module | | **0.1.3** || **[@analytics/aws-pinpoint](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-aws-pinpoint)**
AWS Pinpoint integration for 'analytics' module | | **0.7.7** || **[@analytics/cookie-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-storage-cookie)**
Tiny cookie utility library | | **0.2.10** || **[@analytics/core](https://github.com/DavidWells/analytics/tree/master/packages/analytics-core)**
Lightweight analytics library for tracking events, page views, & identifying users. Works with any third party analytics provider via an extendable plugin system. | | **0.12.2** || **[@analytics/countly](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-countly)**
Countly plugin for 'analytics' module | | **0.21.11** || **[@analytics/crazy-egg](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-crazy-egg)**
Crazy Egg integration for 'analytics' module | | **0.1.2** || **[@analytics/custify](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-custify)**
Custify integration for 'analytics' module for browser & node | | **0.0.2** || **[@analytics/customerio](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-customerio)**
Customer.io integration for 'analytics' module | | **0.2.2** || **[@analytics/form-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-forms)**
Form utility library for managing HTML form submissions & values | | **0.3.11** || **[@analytics/fullstory](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-fullstory)**
Unofficial FullStory plugin for 'analytics' module | | **0.2.6** || **[@analytics/global-storage-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-storage-global)**
Tiny global storage utility library | | **0.1.5** || **[@analytics/google-analytics](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-google-analytics)**
Google analytics v4 plugin for 'analytics' module | | **1.0.5** || **[@analytics/google-tag-manager](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-google-tag-manager)**
Google tag manager plugin for 'analytics' module | | **0.5.3** || **[@analytics/google-analytics-v3](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-google-analytics-v3)**
Google analytics v3 plugin for 'analytics' module | | **0.6.1** || **[@analytics/gosquared](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-gosquared)**
GoSquared integration for 'analytics' module | | **0.1.3** || **[@analytics/hubspot](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-hubspot)**
HubSpot plugin for 'analytics' module | | **0.5.1** || **[@analytics/intercom](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-intercom)**
Intercom integration for 'analytics' module for browser & node | | **1.0.2** || **[@analytics/listener-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-listener)**
Backward compatible event listener library for attaching & detaching event handlers | | **0.3.0** || **[@analytics/localstorage-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-storage-local)**
Tiny LocalStorage utility library | | **0.1.8** || **[@analytics/mixpanel](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-mixpanel)**
Mixpanel plugin for 'analytics' module | | **0.4.0** || **[@analytics/original-source-plugin](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-original-source)**
Save original referral source of visitor plugin for 'analytics' pkg | | **1.0.9** || **[@analytics/ownstats](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-ownstats)**
Ownstats integration for 'analytics' module for browser & node | | **0.1.2** || **[@analytics/perfumejs](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-perfumejs)**
Send browser performance metrics to third-party analytics providers | | **0.2.1** || **[@analytics/queue-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-queue)**
Dependency free queue processor | | **0.1.2** || **[@analytics/redact-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-redact)**
Utility library for redacting event data | | **0.1.1** || **[@analytics/remote-storage-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-storage-remote)**
Storage utilities for cross domain localStorage access, with permissions | | **0.4.18** || **[@analytics/router-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-router)**
Route change utilities for single page apps | | **0.1.1** || **[@analytics/scroll-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-scroll)**
Scroll utility library to fire events on scroll | | **0.1.20** || **[@analytics/segment](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-segment)**
Segment integration for 'analytics' module for browser & node | | **1.1.4** || **[@analytics/session-storage-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-storage-session)**
Tiny SessionStorage utility library | | **0.0.5** || **[@analytics/session-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-session)**
Tiny session utility library | | **0.1.17** || **[@analytics/simple-analytics](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-simple-analytics)**
Simple analytics plugin for 'analytics' module for browser | | **0.3.4** || **[@analytics/snowplow](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-snowplow)**
Snowplow integration for 'analytics' module for browser & node | | **0.3.3** || **[@analytics/storage-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-storage)**
Storage utility with fallbacks | | **0.4.0** || **[@analytics/type-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-types)**
Tiny runtime type checking utils | | **0.6.0** || **[@analytics/url-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-url)**
Url utils | | **0.2.1** || **[@analytics/visitor-source](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-visitor-source)**
Get visitor source | | **0.0.5** || **[analytics-cli](https://github.com/DavidWells/analytics/tree/master/packages/analytics-cli)**
CLI for `analytics` pkg | | **0.0.5** || **[analytics-plugin-do-not-track](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-do-not-track)**
Disable tracking for opted out visitors plugin for 'analytics' module | | **0.1.5** || **[analytics-plugin-event-validation](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-event-validation)**
Event validation plugin for analytics | | **0.1.2** || **[gatsby-plugin-analytics](https://github.com/DavidWells/analytics/tree/master/packages/gatsby-plugin-analytics)**
Easily add analytics to your Gatsby site | | **0.2.0** || **[analytics-plugin-lifecycle-example](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-lifecycle-example)**
Example plugin with lifecycle methods for 'analytics' module | | **0.1.2** || **[analytics-plugin-tab-events](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-tab-events)**
Expose tab visibility events plugin for 'analytics' module | | **0.2.1** || **[use-analytics](https://github.com/DavidWells/analytics/tree/master/packages/use-analytics)**
Analytics hooks for React | | **0.0.5** || **[analytics-util-params](https://github.com/DavidWells/analytics/tree/master/packages/analytics-util-params)**
Url Parameter helper functions | | **0.1.2** || **[analytics-utils](https://github.com/DavidWells/analytics/tree/master/packages/analytics-utils)**
Analytics utility functions used by 'analytics' module | | **1.0.10** || **[analytics-plugin-window-events](https://github.com/DavidWells/analytics/tree/master/packages/analytics-plugin-window-events)**
Expose window events plugin for 'analytics' module | | **0.0.7** |

Community Plugins


Below are plugins created outside of this repo:

- ActiveCampaign Adds Analytics support for ActiveCampaign
- analytics-fetch Integration with the browser's fetch API for analytics
- Facebook tracking pixel Send data to Facebook Tracking pixel
- Indicative Adds Analytics support for Indicative
- LinkedIn Pixel Adds Analytics support for Linkedin tracking pixel
- Logrocket Adds Analytics support for LogRocket
- Plausible Adds Analytics support for Plausible
- ProfitWell Adds Analytics support for ProfitWell
- Reddit Pixel Adds Analytics support for Reddit Pixel
- RudderStack Adds Analytics support for RudderStack
- Splitbee Adds Analytics support for Splitbee
- Tapfiliate Adds Analytics support for Tapfiliate
- Yandex Send data to Yandex metrica

Additional examples


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 to register and call.

Here is a quick example of a plugin:

  1. ``` js
  2. // plugin-example.js
  3. export default function pluginExample(userConfig) {
  4.   // return object for analytics to use
  5.   return {
  6.     /* All plugins require a name */
  7.     name: 'my-example-plugin',
  8.     /* Everything else below this is optional depending on your plugin requirements */
  9.     config: {
  10.       whatEver: userConfig.whatEver,
  11.       elseYouNeed: userConfig.elseYouNeed
  12.     },
  13.     initialize: ({ config }) => {
  14.       // load provider script to page
  15.     },
  16.     page: ({ payload }) => {
  17.       // call provider specific page tracking
  18.     },
  19.     track: ({ payload }) => {
  20.       // call provider specific event tracking
  21.     },
  22.     identify: ({ payload }) => {
  23.       // call provider specific user identify method
  24.     },
  25.     loaded: () => {
  26.       // return boolean so analytics knows when it can send data to third-party
  27.       return !!window.myPluginLoaded
  28.     }
  29.   }
  30. }
  31. ```

name is required for all plugins. All other methods are optional.

If you don't need to hook into page tracking, just omit the page key from your plugin object.

To use a plugin, import it and pass it into the plugins array when you bootstrap analytics.

  1. ``` js
  2. import Analytics from 'analytics'
  3. import pluginExample from './plugin-example.js'

  4. const analytics = Analytics({
  5.   app: 'my-app-name',
  6.   plugins: [
  7.     pluginExample({
  8.       whatEver: 'hello',
  9.       elseYouNeed: 'there'
  10.     }),
  11.     ...otherPlugins
  12.   ]
  13. })
  14. ```

React to any event


Plugins can react to any event flowing through the analytics library.

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](https://github.com/DavidWells/analytics/blob/master/packages/analytics-core/src/events.js).

  1. ``` js
  2. // Example Plugin plugin.js
  3. export default function myPlugin(userConfig) {
  4.   return {
  5.     /* Name is a required field for plugins */
  6.     name: 'my-plugin',
  7.     /* Bootstrap runs when analytics starts */
  8.     bootstrap: ({ payload, config, instance }) => {
  9.       // Do whatever on `bootstrap` event
  10.     },
  11.     pageStart: ({ payload, config, instance }) => {
  12.       // Fire custom logic before analytics.page() calls
  13.     },
  14.     pageEnd: ({ payload, config, instance }) => {
  15.       // Fire custom logic after analytics.page() calls
  16.     },
  17.     trackStart: ({ payload, config, instance }) => {
  18.       // Fire custom logic before analytics.track() calls
  19.     },
  20.     'track:customerio': ({ payload, config, instance }) => {
  21.       // Fire custom logic before customer.io plugin runs.
  22.       // Here you can customize the data sent to individual analytics providers
  23.     },
  24.     trackEnd: ({ payload, config, instance }) => {
  25.       // Fire custom logic after analytics.track() calls
  26.     },
  27.     // ... hook into other events
  28.   }
  29. }
  30. ```

Using this plugin is the same as any other.

  1. ``` js
  2. import Analytics from 'analytics'
  3. import customerIoPlugin from '@analytics/customerio'
  4. import myPlugin from './plugin.js'

  5. const analytics = Analytics({
  6.   app: 'my-app-name',
  7.   plugins: [
  8.     // include myPlugin
  9.     myPlugin(),
  10.     customerIoPlugin({
  11.       trackingId: '1234'
  12.     })
  13.     ...otherPlugins
  14.   ]
  15. })
  16. ```

Custom methods


Analytics plugins can provide their own custom functionality via the methods key.

  1. ``` js
  2. import Analytics from 'analytics'

  3. // Example plugin with custom methods
  4. const pluginOne = {
  5.   name: 'one',
  6.   // ... page, track, etc
  7.   // Custom functions to expose to analytics instance
  8.   methods: {
  9.     myCustomThing(one, two, three) {
  10.       const analyticsInstance = this.instance
  11.       console.log('Use full analytics instance', analyticsInstance)
  12.     },
  13.     otherCustomThing: (one, two, ...args) => {
  14.       // Arrow functions break this.instance context.
  15.       // The instance is instead injected as last arg
  16.       const analyticsInstance = args[args.length - 1]
  17.       console.log('Use full analytics instance', analyticsInstance)
  18.     },
  19.     // Async function examples
  20.     async fireCustomThing(one, two, three) {
  21.       const { track } = this.instance
  22.       track('customThing')
  23.       return 'data'
  24.     },
  25.     triggerSpecial: async (argOne, argTwo, ...args) => {
  26.       // Arrow functions break this.instance context.
  27.       // The instance is instead injected as last arg
  28.       const analyticsInstance = args[args.length - 1]
  29.       return argOne + argTwo
  30.     }
  31.   }
  32. }

  33. // Example plugin with custom methods
  34. const pluginTwo = {
  35.   name: 'two',
  36.   page: () => { console.log('page view fired') }
  37.   // Custom functions to expose to analytics instance
  38.   methods: {
  39.     cookieBanner(one, two, three) {
  40.       const analyticsInstance = this.instance
  41.       console.log('Use full analytics instance', analyticsInstance)
  42.       const cookieSettings = analyticsInstance.storage.getItem('preferences-set')
  43.       if (!cookieSettings) {
  44.         // Show cookie settings
  45.       }
  46.     },
  47.   }
  48. }

  49. // Initialize analytics instance with plugins
  50. const analytics = Analytics({
  51.   app: 'your-app-name',
  52.   plugins: [
  53.     pluginOne,
  54.     pluginTwo
  55.   ]
  56. })

  57. // Using custom methods in your code
  58. analytics.plugins.one.myCustomThing()
  59. analytics.plugins.two.cookieBanner()
  60. ```

Plugin Naming Conventions


Plugins should follow this naming convention before being published to npm

  1. ``` sh
  2. analytics-plugin-{your-plugin-name}
  3. ```

E.g. An analytics plugin that does awesome-stuff should be named

  1. ``` sh
  2. npm install analytics-plugin-awesome-stuff
  3. ```

Then submit to the list above

Debugging analytics


During development, you can turn on debug mode. This will connect the dev tools for you to see the analytics events passing through your application visually.

analytics-debug-tools

  1. ``` js
  2. import Analytics from 'analytics'

  3. const analytics = Analytics({
  4.   app: 'my-app',
  5.   debug: true
  6. })
  7. ```

TypeScript support


Types for analytics and plugins are generated from JSDoc blocks in the code base via the tsd-jsdoc package.

We are always looking to improve type support & improve the DX of users. If you see something that can be improved let us know in an issue!

Contributing


Contributions are always welcome, no matter how large or small. Before contributing, please read the code of conduct.

Setup & Install dependencies


Clone the repo and run

  1. ```sh
  2. $ git clone https://github.com/davidwells/analytics
  3. $ cd analytics
  4. $ npm install && npm run setup
  5. ```

The above command will set up all the packages and their dependencies.

Development


You can watch and rebuild packages with the npm run watch command.

  1. ```sh
  2. npm run watch
  3. ```

While watch mode is activated, you can work against the demo site in examples to test out your changes on a live application.