Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

Commit 4c3a42f

Browse files
feat(vuex): add vuex middleware
the middleware will make possible to call the tracking system from the vuex store action by passing the meta.analytics array inside the payload close #89
1 parent 9f1d3a2 commit 4c3a42f

File tree

9 files changed

+209
-8
lines changed

9 files changed

+209
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ npm install vue-analytics
4747
* [Custom methods](/docs/custom-methods.md)
4848
* [Ecommerce](/docs/ecommerce.md)
4949
* [Untracked hits](/docs/untracked-hits.md)
50+
* [Vuex](/docs/vuex.md)
5051
* [Debug](/docs/debug.md)
5152

5253
# Issues and features requests

SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@
1717
* [Custom methods](/docs/custom-methods.md)
1818
* [Ecommerce](/docs/ecommerce.md)
1919
* [Untracked hits](/docs/untracked-hits.md)
20+
* [Vuex](/docs/vuex.md)
2021
* [Debug](/docs/debug.md)

__tests__/create-trackers.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ it ('should initialize single tracker', () => {
1515

1616
createTrackers()
1717
expect(window.ga).toBeCalledWith('create', config.id, 'auto', {})
18-
expect(window.ga).not.toBeCalledWith('set', 'sendHitTask', null)
18+
expect(window.ga).toBeCalledWith('set', 'sendHitTask', null)
1919
})
2020

2121
it ('should initialize multiple trackers', () => {

config/scripts/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const webpackConfig = merge.smart({}, base, {
3232
asset: '[path].gz[query]',
3333
algorithm: 'gzip',
3434
test: /\.js$/,
35-
threshold: 10240,
35+
threshold: 0,
3636
minRatio: 0.8
3737
}),
3838
new webpack.optimize.ModuleConcatenationPlugin()

docs/debug.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ Implements Google Analaytics debug library.
44

55
**Please remember that it is for debug only. The file size of analytics\_debug.js is way larger than analytics.js**
66

7+
Example:
8+
79
```js
810
Vue.use(VueAnalytics, {
911
id: 'UA-XXX-X',
1012
debug: {
11-
enabled: true,
12-
trace: false,
13-
sendHitTask: true
13+
enabled: false, // default: enabled only if NODE_ENV !== 'production'
14+
trace: false, // default: false
15+
sendHitTask: false // default: enabled only if NODE_ENV === 'production'
1416
}
1517
})
1618
```

docs/vuex.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
## Vuex and Google Analytics
2+
3+
Google Analytics it is now supported also using the Vuex store, by installing the `analyticsMiddleware` plugin
4+
5+
### Install
6+
7+
```js
8+
// store.js
9+
import Vuex from 'vuex'
10+
import Vue from 'vue'
11+
import { analyticsMiddleware } from 'vue-analytics'
12+
13+
Vue.use(Vuex)
14+
15+
const store = new Vuex.Store({
16+
state: {},
17+
actions: {},
18+
mutations: {},
19+
plugins: [
20+
analyticsMiddleware
21+
]
22+
})
23+
24+
export default store
25+
```
26+
27+
```js
28+
// main.js
29+
import Vue from 'vue'
30+
import VueAnalytics from 'vue-analytics'
31+
import store from './store.js'
32+
33+
Vue.use(VueAnalytics, {
34+
id: 'UA-1234-5'
35+
})
36+
37+
new Vue({
38+
...
39+
})
40+
```
41+
42+
### Usage
43+
44+
In the action, when sending a payload, we need to specify a `meta` object with an `analytics` property that will help us send all the data we need to the trackers
45+
46+
Example of a store action
47+
48+
```js
49+
const store = Vuex.Store({
50+
state: {
51+
counter: 0
52+
},
53+
actions: {
54+
increase ({ commit }) {
55+
commit('increaseCounter', {
56+
// Here some extra parameters to pass to the mutation
57+
amount: 1,
58+
59+
// The meta tag will be read by the plugin and fire
60+
// the corresponding events
61+
meta: {
62+
analytics: [
63+
['event', {
64+
eventCategory: 'counter',
65+
eventAction: 'increase',
66+
eventLabel: 'counter experiment',
67+
eventValue: 1
68+
}]
69+
]
70+
}
71+
72+
})
73+
}
74+
}
75+
})
76+
```
77+
78+
The way we can construct the track method is just by creating an array and the first argument will be one of the methods available in `vue-analytics` API
79+
80+
* event
81+
* exception
82+
* page
83+
* query
84+
* require
85+
* set
86+
* social
87+
* time
88+
* untracked
89+
* ecommerce
90+
* commands
91+
92+
the second parameter will be our data as usual constructed in a normal call, so if in a component we will have
93+
94+
```js
95+
export default {
96+
name: 'MyComponent',
97+
methods: {
98+
clickMe () {
99+
this.$ga.event({
100+
eventCategory: 'counter',
101+
eventAction: 'increase',
102+
eventLabel: 'counter experiment',
103+
eventValue: 1
104+
})
105+
}
106+
}
107+
}
108+
```
109+
110+
or
111+
112+
```js
113+
export default {
114+
name: 'MyComponent',
115+
methods: {
116+
clickMe () {
117+
this.$ga.event('counter', 'increase', 'counter experiment', 1)
118+
}
119+
}
120+
}
121+
```
122+
123+
then in our Vuex action we will write
124+
125+
```js
126+
commit('increaseCounter', {
127+
meta: {
128+
analytics: [
129+
['event', {
130+
eventCategory: 'counter',
131+
eventAction: 'increase',
132+
eventLabel: 'counter experiment',
133+
eventValue: 1
134+
}]
135+
]
136+
}
137+
})
138+
```
139+
140+
or
141+
142+
```js
143+
commit('increaseCounter', {
144+
meta: {
145+
analytics: [
146+
['event', 'counter', 'increase', 'counter experiment', 1]
147+
]
148+
}
149+
})
150+
```
151+
152+
### Multiple events
153+
154+
The `analytics` property inside the `meta` object is an array, so it is possible to fire multiple events with one action
155+
156+
```js
157+
commit('someAction', {
158+
meta: {
159+
analytics: [
160+
['event', 'counter', 'increase', 'counter experiment', 1],
161+
['page', '/about'],
162+
['set', 'userId', 12345]
163+
]
164+
}
165+
})
166+
```

src/config.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { merge, noop } from './helpers'
22

3+
const isProduction = process.env.NODE_ENV === 'production'
4+
35
const defaultConfig = {
46
id: null,
57
router: null,
@@ -31,9 +33,9 @@ const defaultConfig = {
3133
},
3234

3335
debug: {
34-
enabled: false,
36+
enabled: !isProduction,
3537
trace: false,
36-
sendHitTask: true
38+
sendHitTask: isProduction
3739
},
3840

3941
checkDuplicatedScript: false,

src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { errorHandler } from 'lib/exception'
44
import config, { update } from './config'
55
import { onAnalyticsReady } from './helpers'
66
import ga from 'directives/ga'
7+
import analyticsMiddleware from './vuex/analyticsMiddleware'
78

89
export default function install (Vue, options = {}) {
910
update(options)
@@ -20,5 +21,6 @@ export default function install (Vue, options = {}) {
2021
}
2122

2223
export {
23-
onAnalyticsReady
24+
onAnalyticsReady,
25+
analyticsMiddleware
2426
}

src/vuex/analyticsMiddleware.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import query from '../lib/query'
2+
import lib from '../lib'
3+
4+
export default store => {
5+
store.subscribe((mutation, state) => {
6+
if (!mutation.payload || !mutation.payload.meta) {
7+
return
8+
}
9+
10+
const { analytics } = mutation.payload.meta
11+
12+
if (!Array.isArray(analytics)) {
13+
throw new Error('The "analytics" property needs to be an array')
14+
}
15+
16+
analytics.forEach(event => {
17+
const type = event.shift()
18+
const props = event
19+
20+
if (!(type in lib)) {
21+
throw new Error(`The type "${type}" doesn't exist.`)
22+
}
23+
24+
lib[type](...props)
25+
})
26+
})
27+
}

0 commit comments

Comments
 (0)