├── renovate.json
├── package.json
├── index.js
├── templates
├── route.js
└── directive.js
├── .gitignore
└── readme.md
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "@nuxtjs"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nuxt-event-trace",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "author": "clark",
6 | "license": "MIT",
7 | "peerDependencies": {
8 | "axios": "^0.17.0",
9 | "vue": "~2.4.2"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('path')
2 |
3 | const resolvePath = (...args) => resolve(__dirname, ...args)
4 |
5 | module.exports = function trace (options) {
6 | if (options.pageApi) {
7 | this.addPlugin({
8 | src: resolvePath('templates/route.js'),
9 | fileName: 'event-trace-route.js',
10 | options
11 | })
12 | }
13 | if (options.elementApi) {
14 | this.addPlugin({
15 | src: resolvePath('templates/directive.js'),
16 | fileName: 'event-trace-directive.js',
17 | options
18 | })
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/templates/route.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | export default ({ app: { router } }, inject) => {
4 | // eslint-disable-next-line no-constant-condition
5 | if (!'<%= options.pageApi %>') {
6 | console.warn('Warn: pageApi is not found in event-trace module options')
7 | return
8 | }
9 | router.afterEach(function (to, from) {
10 | const info = {
11 | from: from.name,
12 | fromPath: from.path,
13 | to: to.name,
14 | toPath: to.path,
15 | params: to.params,
16 | time: new Date()
17 | }
18 | axios.post('<%= options.pageApi %>', info)
19 | })
20 | }
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/node
3 |
4 | ### Node ###
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 |
24 | # nyc test coverage
25 | .nyc_output
26 |
27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
28 | .grunt
29 |
30 | # Bower dependency directory (https://bower.io/)
31 | bower_components
32 |
33 | # node-waf configuration
34 | .lock-wscript
35 |
36 | # Compiled binary addons (http://nodejs.org/api/addons.html)
37 | build/Release
38 |
39 | # Dependency directories
40 | node_modules/
41 | jspm_packages/
42 |
43 | # Typescript v1 declaration files
44 | typings/
45 |
46 | # Optional npm cache directory
47 | .npm
48 |
49 | # Optional eslint cache
50 | .eslintcache
51 |
52 | # Optional REPL history
53 | .node_repl_history
54 |
55 | # Output of 'npm pack'
56 | *.tgz
57 |
58 | # Yarn Integrity file
59 | .yarn-integrity
60 |
61 | # dotenv environment variables file
62 | .env
63 |
64 |
65 | # End of https://www.gitignore.io/api/node
66 |
67 | yarn.lock
68 |
--------------------------------------------------------------------------------
/templates/directive.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import axios from 'axios'
3 |
4 | class TraceEvent {
5 | bind (el, binding, vnode) {
6 | // eslint-disable-next-line no-constant-condition
7 | if (!'<%= options.elementApi %>') {
8 | console.warn('Warn: elementApi is not found in event-trace module options')
9 | return
10 | }
11 | if (!binding) return
12 | if (typeof binding.value !== 'object') {
13 | console.warn('v-trace value is not a object in ' + binding.rawName)
14 | return
15 | }
16 |
17 | // passing parameters as object
18 | const {category, action, label, value, nodeId} = binding.value
19 | const info = {category, action, label, value, nodeId, time: new Date()}
20 |
21 | // use modifier as events
22 | const events = Object.keys(binding.modifiers).map(modifier => {
23 | if (binding.modifiers[modifier]) {
24 | return modifier
25 | }
26 | })
27 |
28 | // addEventListener for each event, call trackEvent api
29 | if (!events.length) events.push('click') // listen click event by default
30 | events.forEach((event) => {
31 | el.addEventListener(event, () => {
32 | axios.post('<%= options.elementApi %>', info)
33 | }, false)
34 | })
35 | }
36 | }
37 |
38 | Vue.directive('trace', new TraceEvent())
39 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## Module for event trace in Nuxt.js
2 |
3 | ### Install
4 |
5 | ```bash
6 | $ yarn add nuxt-event-trace
7 | ```
8 |
9 | Add module into `nuxt.config.js`.
10 |
11 | 1. `elementApi` is api url for dom elements tracking.
12 | 1. `pageApi` is api url for pages routing tracking.
13 |
14 | ```js
15 | modules: [
16 | ['./client/modules/event-trace', {
17 | elementApi: "http://example.com/api/trace",
18 | pageApi: "http://example.com/route/trace"
19 | }]
20 | ]
21 | ```
22 |
23 | ### Trace on routes
24 |
25 | If defined `pageApi`, all routes will be logged after routing.
26 |
27 | ### Trace on component
28 |
29 | Define `v-trace` directive on `component`.
30 |
31 | ```html
32 |
34 |
35 |
37 |
38 | ```
39 |
40 | 1. Value items include: `category`, `action`, `label`, `value`, `nodeId`
41 | 1. [Event Type](https://developer.mozilla.org/en-US/docs/Web/Events) is defined as modifiers, `click` is default if no type specified.
42 |
43 | ```html
44 |
45 |
46 |
47 | ```
48 |
--------------------------------------------------------------------------------