Skip to content

Commit 29f3c82

Browse files
ekoztrusktrsy-recordsjhildenbiddlezhanzhao
authored
feat: add google analytics gtag.js plugin (#1702)
Co-authored-by: Joe Pea <joe@trusktr.io> Co-authored-by: 沈唁 <52o@qq52o.cn> Co-authored-by: John Hildenbiddle <jhildenbiddle@users.noreply.github.com> Co-authored-by: zhanzhao <zhanzhao@megvii.com>
1 parent a8a25d0 commit 29f3c82

File tree

4 files changed

+197
-0
lines changed

4 files changed

+197
-0
lines changed

build/build.js

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ async function buildAllPlugin() {
8080
var plugins = [
8181
{name: 'search', input: 'search/index.js'},
8282
{name: 'ga', input: 'ga.js'},
83+
{name: 'gtag', input: 'gtag.js'},
8384
{name: 'matomo', input: 'matomo.js'},
8485
{name: 'emoji', input: 'emoji.js'},
8586
{name: 'external-script', input: 'external-script.js'},

docs/plugins.md

+27
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ This plugin ignores diacritical marks when performing a full text search (e.g.,
7171

7272
## Google Analytics
7373

74+
> Google's Universal Analytics service will no longer process new data in standard properties beginning July 1, 2023. Prepare now by setting up and switching over to a Google Analytics 4 property and docsify's gtag.js plugin.
75+
7476
Install the plugin and configure the track id.
7577

7678
```html
@@ -91,6 +93,31 @@ Configure by `data-ga`.
9193
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
9294
```
9395

96+
## Google Analytics 4 (GA4)
97+
98+
Install the plugin and configure the track id.
99+
100+
```html
101+
<script>
102+
// Single ID
103+
window.$docsify = {
104+
gtag: 'UA-XXXXX-Y',
105+
};
106+
107+
// Multiple IDs
108+
window.$docsify = {
109+
gtag: [
110+
'G-XXXXXXXX', // Google Analytics 4 (GA4)
111+
'UA-XXXXXXXX', // Google Universal Analytics (GA3)
112+
'AW-XXXXXXXX', // Google Ads
113+
'DC-XXXXXXXX', // Floodlight
114+
],
115+
};
116+
</script>
117+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
118+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gtag.min.js"></script>
119+
```
120+
94121
## Emoji
95122

96123
Renders a larger collection of emoji shorthand codes. Without this plugin, Docsify is able to render only a limited number of emoji shorthand codes.

src/plugins/gtag.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* eslint-disable no-console */
2+
// From ./ga.js
3+
4+
function appendScript(id) {
5+
const script = document.createElement('script');
6+
script.async = true;
7+
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + id;
8+
document.body.appendChild(script);
9+
}
10+
11+
// global site tag instance initialized
12+
function initGlobalSiteTag(id) {
13+
appendScript(id);
14+
15+
window.dataLayer = window.dataLayer || [];
16+
window.gtag =
17+
window.gtag ||
18+
function () {
19+
window.dataLayer.push(arguments);
20+
};
21+
22+
window.gtag('js', new Date());
23+
window.gtag('config', id);
24+
}
25+
26+
// add additional products to your tag
27+
// https://developers.google.com/tag-platform/gtagjs/install
28+
function initAdditionalTag(id) {
29+
window.gtag('config', id);
30+
}
31+
32+
function init(ids) {
33+
if (Array.isArray(ids)) {
34+
// set the first id to be a global site tag
35+
initGlobalSiteTag(ids[0]);
36+
37+
// the rest ids
38+
ids.forEach((id, index) => {
39+
if (index > 0) {
40+
initAdditionalTag(id);
41+
}
42+
});
43+
} else {
44+
initGlobalSiteTag(ids);
45+
}
46+
}
47+
48+
function collect() {
49+
if (!window.gtag) {
50+
init($docsify.gtag);
51+
}
52+
53+
// usage: https://developers.google.com/analytics/devguides/collection/gtagjs/pages
54+
window.gtag('event', 'page_view', {
55+
/* eslint-disable camelcase */
56+
page_title: document.title,
57+
page_location: location.href,
58+
page_path: location.pathname,
59+
/* eslint-disable camelcase */
60+
});
61+
}
62+
63+
const install = function (hook) {
64+
if (!$docsify.gtag) {
65+
console.error('[Docsify] gtag is required.');
66+
return;
67+
}
68+
69+
hook.beforeEach(collect);
70+
};
71+
72+
$docsify.plugins = [].concat(install, $docsify.plugins);

test/e2e/gtag.test.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Modules, constants, and variables
2+
// npm run test:e2e gtag.test.js
3+
// -----------------------------------------------------------------------------
4+
const docsifyInit = require('../helpers/docsify-init');
5+
const { test, expect } = require('./fixtures/docsify-init-fixture');
6+
7+
const gtagList = [
8+
'AW-YYYYYY', // Google Ads
9+
'DC-ZZZZZZ', // Floodlight
10+
'G-XXXXXX', // Google Analytics 4 (GA4)
11+
'UA-XXXXXX', // Google Universal Analytics (GA3)
12+
];
13+
14+
// Suite
15+
// -----------------------------------------------------------------------------
16+
test.describe('Gtag Plugin Tests', () => {
17+
// page request listened, print collect url
18+
function pageRequestListened(page) {
19+
page.on('request', request => {
20+
if (request.url().indexOf('www.google-analytics.com') !== -1) {
21+
// console.log(request.url());
22+
}
23+
});
24+
25+
page.on('response', response => {
26+
const request = response.request();
27+
// googleads.g.doubleclick.net
28+
// www.google-analytics.com
29+
// www.googletagmanager.com
30+
const reg =
31+
/googleads\.g\.doubleclick\.net|www\.google-analytics\.com|www\.googletagmanager\.com/g;
32+
if (request.url().match(reg)) {
33+
// console.log(request.url(), response.status());
34+
}
35+
});
36+
}
37+
38+
// Tests
39+
// ---------------------------------------------------------------------------
40+
test('single gtag', async ({ page }) => {
41+
pageRequestListened(page);
42+
43+
const docsifyInitConfig = {
44+
config: {
45+
gtag: gtagList[0],
46+
},
47+
scriptURLs: ['/lib/plugins/gtag.min.js'],
48+
styleURLs: ['/lib/themes/vue.css'],
49+
};
50+
51+
await docsifyInit({
52+
...docsifyInitConfig,
53+
});
54+
55+
const $docsify = await page.evaluate(() => window.$docsify);
56+
57+
// Verify config options
58+
expect(typeof $docsify).toEqual('object');
59+
60+
// console.log($docsify.gtag, $docsify.gtag === '');
61+
62+
// Tests
63+
expect($docsify.gtag).not.toEqual('');
64+
});
65+
66+
test('multi gtag', async ({ page }) => {
67+
pageRequestListened(page);
68+
69+
const docsifyInitConfig = {
70+
config: {
71+
gtag: gtagList,
72+
},
73+
scriptURLs: ['/lib/plugins/gtag.min.js'],
74+
styleURLs: ['/lib/themes/vue.css'],
75+
};
76+
77+
await docsifyInit({
78+
...docsifyInitConfig,
79+
});
80+
81+
const $docsify = await page.evaluate(() => window.$docsify);
82+
83+
// Verify config options
84+
expect(typeof $docsify).toEqual('object');
85+
86+
// console.log($docsify.gtag, $docsify.gtag === '');
87+
88+
// Tests
89+
expect($docsify.gtag).not.toEqual('');
90+
});
91+
92+
test('data-ga attribute', async ({ page }) => {
93+
pageRequestListened(page);
94+
95+
// TODO
96+
});
97+
});

0 commit comments

Comments
 (0)