Skip to content

Commit 3e5590b

Browse files
committed
add plugin code
1 parent fe4bfc7 commit 3e5590b

File tree

4 files changed

+190
-2
lines changed

4 files changed

+190
-2
lines changed

README.md

+72-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,77 @@
11
# VuePress Plugin Minimal Google Analytics
22

3-
Minimal Google analytics plugin for vuepress
3+
> Minimal Google Analytics plugin for VuePress 1.x
4+
5+
[![npm version](https://img.shields.io/npm/v/vuepress-plugin-minimal-analytics.svg?style=flat-square)](http://npm.im/vuepress-plugin-minimal-analytics)
6+
[![MIT License](https://img.shields.io/npm/l/express.svg?style=flat-square)](http://opensource.org/licenses/MIT)
7+
8+
9+
## Why
10+
11+
Because sometimes all you need is just the page views
12+
without all the bloated libraries.
13+
14+
15+
## What
16+
17+
This plugin is based on the official VuePress plugin [@vuepress/plugin-google-analytics](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-google-analytics) - [npm](https://www.npmjs.com/package/@vuepress/plugin-google-analytics).
18+
19+
The difference betweeen this plugin and the official one is that it uses a light
20+
version of the tracking code as introduced
21+
by 🌱 [minimalanalytics.com](https://minimalanalytics.com/) - source code in [this gist](https://gist.github.com/DavidKuennen/443121e692175d6fc145e1efb0284ec9).
22+
23+
24+
## Install
25+
26+
27+
```sh
28+
$ npm install -D vuepress-plugin-minimal-analytics
29+
30+
# or
31+
32+
$ yarn add -D vuepress-plugin-minimal-analytics
33+
```
34+
35+
36+
## Usage
37+
38+
Add `vuepress-plugin-minimal-analytics` in your site or theme config file.
39+
40+
> See [official docs on using a plugin](https://vuepress.vuejs.org/plugin/using-a-plugin.html)
41+
42+
43+
```js
44+
// .vuepress/config.js
45+
// or
46+
// .vuepress/theme/index.js
47+
48+
// replace 'XX-XXXXXXXXX-X' with your tracking id
49+
module.exports = {
50+
plugins: ['minimal-analytics', {ga: 'XX-XXXXXXXXX-X'}],
51+
}
52+
```
53+
54+
55+
## Options
56+
57+
> See Plugin Option API [official docs](https://vuepress.vuejs.org/plugin/option-api.html)
58+
59+
### ga
60+
61+
- Type: `string`
62+
- Default: `undefined`
63+
64+
Provide the Google Analytics ID to enable integration.
65+
66+
67+
## Reference
68+
69+
- VuePress official [plugin docs](https://vuepress.vuejs.org/plugin/)
70+
- VuePress official [@vuepress/plugin-google-analytics](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-google-analytics) - [npm](https://www.npmjs.com/package/@vuepress/plugin-google-analytics)
71+
- Minimal Analytics Snippet [Gist](https://gist.github.com/DavidKuennen/443121e692175d6fc145e1efb0284ec9)
72+
by [@DavidKuennen](https://github.com/DavidKuennen)
73+
- Google Analytics official [endpoint documentation](https://developers.google.com/analytics/devguides/collection/protocol/v1/reference)
74+
475

576
## License
677

index.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const { path } = require('@vuepress/shared-utils')
2+
3+
module.exports = (options = {}, context) => ({
4+
define () {
5+
const { siteConfig = {}} = context
6+
const ga = options.ga || siteConfig.ga
7+
const GA_ID = ga || false
8+
return { GA_ID }
9+
},
10+
11+
enhanceAppFiles: [
12+
path.resolve(__dirname, 'inject.js')
13+
]
14+
})

inject.js

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/* global GA_ID, ga */
2+
3+
export default ({ router }) => {
4+
// Google analytics integration
5+
if (process.env.NODE_ENV === 'production' && GA_ID && typeof window !== 'undefined') {
6+
7+
// snippet source: https://gist.github.com/DavidKuennen/443121e692175d6fc145e1efb0284ec9
8+
(function (context, trackingId, options) {
9+
const history = context.history;
10+
const doc = document;
11+
const nav = navigator || {};
12+
const storage = localStorage;
13+
const encode = encodeURIComponent;
14+
const pushState = history.pushState;
15+
const typeException = 'exception';
16+
const generateId = () => Math.random().toString(36);
17+
const getId = () => {
18+
if (!storage.cid) {
19+
storage.cid = generateId()
20+
}
21+
return storage.cid;
22+
};
23+
const serialize = (obj) => {
24+
var str = [];
25+
for (var p in obj) {
26+
if (obj.hasOwnProperty(p)) {
27+
if(obj[p] !== undefined) {
28+
str.push(encode(p) + "=" + encode(obj[p]));
29+
}
30+
}
31+
}
32+
return str.join("&");
33+
};
34+
const track = (
35+
type,
36+
eventCategory,
37+
eventAction,
38+
eventLabel,
39+
eventValue,
40+
exceptionDescription,
41+
exceptionFatal
42+
) => {
43+
const url = 'https://www.google-analytics.com/collect';
44+
const data = serialize({
45+
v: '1',
46+
ds: 'web',
47+
aip: options.anonymizeIp ? 1 : undefined,
48+
tid: trackingId,
49+
cid: getId(),
50+
t: type || 'pageview',
51+
sd: options.colorDepth && screen.colorDepth ? `${screen.colorDepth}-bits` : undefined,
52+
dr: doc.referrer || undefined,
53+
dt: doc.title,
54+
dl: doc.location.origin + doc.location.pathname + doc.location.search,
55+
ul: options.language ? (nav.language || "").toLowerCase() : undefined,
56+
de: options.characterSet ? doc.characterSet : undefined,
57+
sr: options.screenSize ? `${(context.screen || {}).width}x${(context.screen || {}).height}` : undefined,
58+
vp: options.screenSize && context.visualViewport ? `${(context.visualViewport || {}).width}x${(context.visualViewport || {}).height}` : undefined,
59+
ec: eventCategory || undefined,
60+
ea: eventAction || undefined,
61+
el: eventLabel || undefined,
62+
ev: eventValue || undefined,
63+
exd: exceptionDescription || undefined,
64+
exf: typeof exceptionFatal !== 'undefined' && !!exceptionFatal === false ? 0 : undefined,
65+
});
66+
67+
if(nav.sendBeacon) {
68+
nav.sendBeacon(url, data)
69+
} else {
70+
var xhr = new XMLHttpRequest();
71+
xhr.open("POST", url, true);
72+
xhr.send(data);
73+
}
74+
};
75+
const trackEvent = (category, action, label, value) => track('event', category, action, label, value);
76+
const trackException = (description, fatal) => track(typeException, null, null, null, null, description, fatal);
77+
history.pushState = function (state) {
78+
if (typeof history.onpushstate == "function") {
79+
history.onpushstate({ state: state });
80+
}
81+
setTimeout(track, options.delay || 10);
82+
return pushState.apply(history, arguments);
83+
}
84+
track();
85+
context.ma = {
86+
trackEvent,
87+
trackException
88+
}
89+
})(window, GA_ID, {
90+
anonymizeIp: true,
91+
colorDepth: true,
92+
characterSet: true,
93+
screenSize: true,
94+
language: true
95+
});
96+
97+
router.afterEach(function (to) {
98+
ga('set', 'page', to.fullPath)
99+
ga('send', 'pageview')
100+
})
101+
}
102+
}
103+

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vuepress-plugin-minimal-analytics",
33
"version": "0.0.1",
4-
"description": "Minimal Google analytics plugin for vuepress",
4+
"description": "Minimal Google Analytics plugin for VuePress",
55
"main": "index.js",
66
"scripts": {},
77
"repository": {

0 commit comments

Comments
 (0)