Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

redux-gtm

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redux-gtm - npm Package Compare versions

Comparing version 0.2.2 to 0.3.0

lib/create-events.js

63

index.d.ts

@@ -13,4 +13,4 @@ // Type definitions for redux-gtm

* Use this property to specify the name of the event you want to emit
* for the associated Redux action. If not provided, the event name
* defaults to the Redux action type.
* for the associated action. If not provided, the event name defaults
* to the action type.
*

@@ -20,5 +20,6 @@ * eventFields

* would like to emit with the event. Any function assigned to this
* property will receive the state of the application, and the
* associated action object. Any properties in the object returned by
* the attached function will be emitted along with the event.
* property will receive the state of the application (before the
* action), and the associated action object. Any property named
* "event" in the returned object will override any defaults or any
* event names defined in `eventName`.
*

@@ -28,17 +29,14 @@ * eventSchema

* validation functions for each property in the event that you want
* to validate. If any of these validation functions return false, the
* event will not be emitted.
* to validate. If any of these validation functions return false,
* ReduxGTM will not emit the event.
*/
export interface EventDefinition {
eventName?: string;
eventFields? (prevState: any, action: any): any;
eventSchema?: EventSchema;
}
export type EventDefinition = { eventName: string } | { eventFields(prevState: any, action: any): any } | { eventSchema: EventSchema };
/**
* A map between your Redux actions and your analytics events. Each
* key must be a Redux action type.
* A map between your actions and your analytics events. Each key
* must be an action type. Each property must be a valid
* EventDefinition or an array of EventDefinitions.
*/
export interface EventDefinitionsMap {
[key: string]: EventDefinition;
[key: string]: EventDefinition | Array<EventDefinition>;
}

@@ -58,8 +56,20 @@

interface GAeventProperties {
eventAction?: string,
eventCategory?: string,
eventLabel?: string,
eventValue?: string,
eventAction?: string;
eventCategory?: string;
eventLabel?: string;
eventValue?: string;
}
interface GApageviewProperties {
title?: string;
location?: string;
}
interface GAtimingProperties {
timingCategory?: string;
timingLabel?: string;
timingVar?: string;
timingValue?: number;
}
/**

@@ -75,3 +85,16 @@ * Create an event compatible with Google Analtyics.

*/
function createGApageview(page?: string): any;
function createGApageview(page?: string, pageProps?: GApageviewProperties): any;
/**
* Create a timing event compatible with Google analytics.
* Use with the ga-stater container
*/
function createGAuserTiming(timingProps?: GAtimingProperties): any;
}
declare namespace Extensions {
function logger(): any;
type ConnectivitySelector = (state: any) => boolean;
function offlineWeb(isConnected: ConnectivitySelector): any;
function offlineReactNative(AsyncStorage: any, isConnected: ConnectivitySelector): any;
}
'use strict';
var createEvent = require('./create-event');
var validateEvent = require('./validate-event');
var createEvents = require('./create-events');
var getDataLayer = require('./get-data-layer');
var registerEvents = require('./register-events');
var createMetaReducer = function createMetaReducer(actionsToTrack, customDataLayer) {
function createMetaReducer(eventDefinitionsMap) {
var extensions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return function (reducer) {
return function (state, action) {
var dataLayer = getDataLayer(window, customDataLayer);
return function (prevState, action) {
if (!eventDefinitionsMap[action.type]) {
return reducer(prevState, action);
}
var result = reducer(state, action);
var dataLayer = getDataLayer(window, extensions.customDataLayer);
var eventDefinition = actionsToTrack[action.type];
if (dataLayer === undefined || !eventDefinition) {
return result;
if (dataLayer === undefined) {
return reducer(prevState, action);
}
var event = createEvent(eventDefinition, state, action);
var isValidEvent = validateEvent(event, eventDefinition);
var events = createEvents(eventDefinitionsMap[action.type], prevState, action);
registerEvents(events, dataLayer, prevState, extensions, action);
if (isValidEvent) {
dataLayer.push(event);
}
return result;
return reducer(prevState, action);
};
};
};
}
module.exports = createMetaReducer;
'use strict';
var createEvent = require('./create-event');
var validateEvent = require('./validate-event');
var createEvents = require('./create-events');
var registerEvents = require('./register-events');
var getDataLayer = require('./get-data-layer');
var createMiddleware = function createMiddleware(actionsToTrack, customDataLayer) {
var createMiddleware = function createMiddleware(eventDefinitionsMap) {
var extensions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return function (store) {
return function (next) {
return function (action) {
var dataLayer = getDataLayer(window, customDataLayer);
if (!eventDefinitionsMap[action.type]) {
return next(action);
}
var eventDefinition = actionsToTrack[action.type];
var dataLayer = getDataLayer(window, extensions.customDataLayer);
if (dataLayer === undefined || !eventDefinition) {
if (dataLayer === undefined) {
return next(action);

@@ -20,10 +23,6 @@ }

var prevState = store.getState();
var event = createEvent(eventDefinition, prevState, action);
var isValidEvent = validateEvent(event, eventDefinition);
var events = createEvents(eventDefinitionsMap[action.type], prevState, action);
registerEvents(events, dataLayer, prevState, extensions, action);
if (isValidEvent) {
dataLayer.push(event);
}
return next(action);

@@ -30,0 +29,0 @@ };

'use strict';
function emitGApageview() {
/**
* If pageProps not specified, google analytics could still
* pick up page's title and location.
*/
function createGApageview() {
var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown page';
var pageProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return {
var defaultPageView = {
event: 'REDUX_GTM_GA_EVENT',

@@ -11,4 +16,5 @@ hitType: 'pageview',

};
return Object.assign(defaultPageView, pageProps);
}
module.exports = emitGApageview;
module.exports = createGApageview;

@@ -5,5 +5,10 @@ 'use strict';

var createMetaReducer = require('./create-meta-reducer');
// Extensions
var logger = require('./extensions/logger');
var offlineWeb = require('./extensions/offline-web');
var offlineReactNative = require('./extensions/offline-react-native');
// Event Helpers
var createGAevent = require('./event-helpers/create-ga-event');
var createGApageview = require('./event-helpers/create-ga-pageview');
var createGAuserTiming = require('./event-helpers/create-ga-user-timing');

@@ -13,6 +18,12 @@ module.exports = {

createMetaReducer: createMetaReducer,
Extensions: {
logger: logger,
offlineWeb: offlineWeb,
offlineReactNative: offlineReactNative
},
EventHelpers: {
createGAevent: createGAevent,
createGApageview: createGApageview
createGApageview: createGApageview,
createGAuserTiming: createGAuserTiming
}
};
{
"name": "redux-gtm",
"version": "0.2.2",
"version": "0.3.0",
"description": "Google Tag Manager integration for Redux and ngrx/store",

@@ -13,2 +13,6 @@ "main": "lib/index.js",

"scripts": {
"docs:prepare": "gitbook install",
"docs:watch": "npm run docs:prepare && gitbook serve",
"docs:build": "npm run docs:prepare && rm -rf _book && gitbook build",
"docs:publish": "npm run docs:build && cd _book && git init && git commit --allow-empty -m 'Update docs' && git checkout -b gh-pages && git add . && git commit -am 'Update docs' && git push git@github.com:rangle/redux-gtm gh-pages --force",
"test": "jest",

@@ -46,2 +50,3 @@ "test:watch": "npm test -- --watch",

"eslint-plugin-react": "^6.4.1",
"gitbook-cli": "^2.3.0",
"jest": "^16.0.1",

@@ -48,0 +53,0 @@ "redux": "^3.6.0",

@@ -5,27 +5,52 @@ # ReduxGTM

[![license](https://img.shields.io/github/license/rangle/redux-gtm.svg?style=flat-square)](LICENSE)
[![npm version](https://img.shields.io/npm/v/redux-gtm.svg?style=flat-square)](https://www.npmjs.com/package/redux-gtm)
[![CircleCI](https://img.shields.io/circleci/project/github/rangle/redux-gtm.svg?style=flat-square)](https://circleci.com/gh/rangle/redux-gtm)
[![license](https://img.shields.io/github/license/rangle/redux-gtm.svg)](LICENSE)
[![npm version](https://img.shields.io/npm/v/redux-gtm.svg)](https://www.npmjs.com/package/redux-gtm)
[![CircleCI](https://img.shields.io/circleci/project/github/rangle/redux-gtm.svg)](https://circleci.com/gh/rangle/redux-gtm)
## Getting Started
```bash
npm install --save redux-gtm
```
### Prerequisites
![logger-ext](https://cloud.githubusercontent.com/assets/7446702/20887911/9739e4b4-baca-11e6-8d2d-08db48189d0c.gif)
----
### Quick Start
##### What You Need First
- An app using [Redux](http://redux.js.org/) or [ngrx/store](https://github.com/ngrx/store) to manage state
- A [Google Tag Manager](https://developers.google.com/tag-manager/) account
- A [container snippet](https://developers.google.com/tag-manager/quickstart) in your app's html _(Web)_
- A [Google Tag Manager](https://developers.google.com/tag-manager/) (GTM) account
- An installed GTM [container snippet](https://developers.google.com/tag-manager/quickstart)
### Installation
##### How it Works
In a nutshell, ReduxGTM provides a way for mapping your redux actions to
[custom Gooogle Tag Manager events](https://developers.google.com/tag-manager/devguide#events).
The first step is to create an `EventDefinitionsMap` which maps your
action types to an `EventDefinition`:
With [npm](https://www.npmjs.com/):
```bash
npm install --save redux-gtm
```js
const eventDefinitionsMap = {
'SOME_ACTION_TYPE': {
eventName: 'some-custom-gtm-event',
eventFields: (state, action) => ({
'someEventVariable': action.payload
}),
}
};
```
With [yarn](https://yarnpkg.com/):
```bash
yarn add redux-gtm
The object mapped to `SOME_ACTION_TYPE` is called an
`EventDefinition`. ReduxGTM uses `EventDefinitions` to generate a
custom GTM events. The `EventDefinition` above will produce an event
with following shape:
```js
{
'event': 'some-custom-gtm-event',
'someEventVariable': ... // the value stored in action.payload
}
```
### How it Works
Once we've got an event definitions map, all we have to do is create
the middleware, and apply it to our store.

@@ -36,39 +61,40 @@ ```js

// 1. Import ReduxGTM
// Import ReduxGTM
import { createMiddleware } from 'redux-gtm';
// 2. Create a mapping between you Redux actions and you Google Tag Manager events
const eventDefinitions = {
'SOME_REDUX_ACTION_TYPE': { eventName: 'some-gtm-custom-event' },
// The event definitions map prepared earlier
const eventDefinitionsMap = {
'SOME_ACTION_TYPE': {
eventName: 'some-custom-gtm-event',
eventFields: (state, action) => ({
'someEventVariable': action.payload
}),
}
};
// 3. Create the middleware using createMiddleware from ReduxGTM
const analyticsMiddleware = createMiddleware(eventDefinitions);
// Create the ReduxGTM middleware
const middleware = createMiddleware(eventDefinitionsMap);
// 4. Apply the middleware when creating your Redux store
// Apply the middleware when creating your Redux store
const store = createStore(reducer, applyMiddleware(analyticsMiddleware));
```
Now, whenever your application dispatches `SOME_REDUX_ACTION_TYPE`,
ReduxGTM will emit `some-gtm-custom-event` to Google Tag Manager.
Now, whenever your application dispatches `SOME_ACTION_TYPE`, ReduxGTM
will create the associated custom event and push it to the data layer.
#### Notes
- When mapping actions to events, each action type must be mapped to a
valid [eventDefinition](docs/event-definition.md).
##### What Else Can You Do?
## Examples
- [How do I track pageviews when using React Router?](docs/examples/example1.md)
- [How do I track failure events?](docs/examples/example2.md)
- [How to do mini surveys](docs/examples/example3.md)
* Use ReduxGTM in React Native and Cordova apps
* Track analytics events even if one of your users loses connection
(offline events tracking)
* Use one of our starter containers to get up and running in GTM with
almost zero configuration
* Provide multiple event definitions for a single Redux action
## API
- [createMiddleware](docs/create-middleware.md)([eventDefinitionsMap](docs/event-definitions-map.md), [[dataLayer]](docs/data-layer.md))
- [createMetaReducer](docs/create-meta-reducer.md)([eventDefinitionsMap](docs/event-definitions-map.md), [[dataLayer]](docs/data-layer.md))
- [EventHelpers](docs/event-helpers/event-helpers.md)
- [createGAevent](docs/event-helpers/create-ga-event.md)
- [createGApageview](docs/event-helpers/create-ga-pageview.md)
### Documentation
The [official docs](https://rangle.github.io/redux-gtm/) contain
tutorials, examples, and a comprehensive API reference for the latest
npm version.
## License
This project is licensed under the MIT License - see
the [LICENSE](LICENSE) file for details
### License
This project is licensed under the MIT License.

@@ -1,25 +0,26 @@

const createEvent = require('./create-event');
const validateEvent = require('./validate-event');
const createEvents = require('./create-events');
const getDataLayer = require('./get-data-layer');
const registerEvents = require('./register-events');
const createMetaReducer = (actionsToTrack, customDataLayer) => reducer => (state, action) => {
const dataLayer = getDataLayer(window, customDataLayer);
function createMetaReducer(eventDefinitionsMap, extensions = {}) {
return function (reducer) {
return function (prevState, action) {
if (!eventDefinitionsMap[action.type]) {
return reducer(prevState, action);
}
const result = reducer(state, action);
const dataLayer = getDataLayer(window, extensions.customDataLayer);
const eventDefinition = actionsToTrack[action.type];
if (dataLayer === undefined || !eventDefinition) {
return result;
}
if (dataLayer === undefined) {
return reducer(prevState, action);
}
const event = createEvent(eventDefinition, state, action);
const isValidEvent = validateEvent(event, eventDefinition);
const events = createEvents(eventDefinitionsMap[action.type], prevState, action);
registerEvents(events, dataLayer, prevState, extensions, action);
if (isValidEvent) {
dataLayer.push(event);
}
return reducer(prevState, action);
};
};
}
return result;
};
module.exports = createMetaReducer;

@@ -1,11 +0,13 @@

const createEvent = require('./create-event');
const validateEvent = require('./validate-event');
const createEvents = require('./create-events');
const registerEvents = require('./register-events');
const getDataLayer = require('./get-data-layer');
const createMiddleware = (actionsToTrack, customDataLayer) => store => next => (action) => {
const dataLayer = getDataLayer(window, customDataLayer);
const createMiddleware = (eventDefinitionsMap, extensions = {}) => store => next => (action) => {
if (!eventDefinitionsMap[action.type]) {
return next(action);
}
const eventDefinition = actionsToTrack[action.type];
const dataLayer = getDataLayer(window, extensions.customDataLayer);
if (dataLayer === undefined || !eventDefinition) {
if (dataLayer === undefined) {
return next(action);

@@ -15,10 +17,6 @@ }

const prevState = store.getState();
const event = createEvent(eventDefinition, prevState, action);
const isValidEvent = validateEvent(event, eventDefinition);
const events = createEvents(eventDefinitionsMap[action.type], prevState, action);
registerEvents(events, dataLayer, prevState, extensions, action);
if (isValidEvent) {
dataLayer.push(event);
}
return next(action);

@@ -25,0 +23,0 @@ };

@@ -1,3 +0,7 @@

function emitGApageview(page = 'unknown page') {
return {
/**
* If pageProps not specified, google analytics could still
* pick up page's title and location.
*/
function createGApageview(page = 'unknown page', pageProps = {}) {
const defaultPageView = {
event: 'REDUX_GTM_GA_EVENT',

@@ -7,4 +11,5 @@ hitType: 'pageview',

};
return Object.assign(defaultPageView, pageProps);
}
module.exports = emitGApageview;
module.exports = createGApageview;
const createMiddleware = require('./create-middleware');
const createMetaReducer = require('./create-meta-reducer');
// Extensions
const logger = require('./extensions/logger');
const offlineWeb = require('./extensions/offline-web');
const offlineReactNative = require('./extensions/offline-react-native');
// Event Helpers
const createGAevent = require('./event-helpers/create-ga-event');
const createGApageview = require('./event-helpers/create-ga-pageview');
const createGAuserTiming = require('./event-helpers/create-ga-user-timing');

@@ -10,6 +15,12 @@ module.exports = {

createMetaReducer,
Extensions: {
logger,
offlineWeb,
offlineReactNative,
},
EventHelpers: {
createGAevent,
createGApageview,
createGAuserTiming,
},
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc