Skip to content

Commit 9a854ec

Browse files
author
zhanzhao
committed
feat: add Google Analytics 4 (GA4) gtag.js plugin (#1695)
1 parent 6a3bd84 commit 9a854ec

File tree

5 files changed

+128
-69
lines changed

5 files changed

+128
-69
lines changed

build/build.js

Lines changed: 1 addition & 0 deletions
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

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,42 @@ 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
7779
<script>
78-
// Single ID
7980
window.$docsify = {
8081
ga: 'UA-XXXXX-Y',
8182
};
83+
</script>
84+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
85+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
86+
```
87+
88+
Configure by `data-ga`.
89+
90+
<!-- prettier-ignore -->
91+
```html
92+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js" data-ga="UA-XXXXX-Y"></script>
93+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
94+
```
95+
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+
};
82106
83107
// Multiple IDs
84108
window.$docsify = {
85-
ga: [
109+
gtag: [
86110
'G-XXXXXXXX', // Google Analytics 4 (GA4)
87111
'UA-XXXXXXXX', // Google Universal Analytics (GA3)
88112
'AW-XXXXXXXX', // Google Ads
@@ -91,15 +115,7 @@ Install the plugin and configure the track id.
91115
};
92116
</script>
93117
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
94-
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
95-
```
96-
97-
Configure by `data-ga`, only support single gtag.
98-
99-
<!-- prettier-ignore -->
100-
```html
101-
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js" data-ga="UA-XXXXX-Y"></script>
102-
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
118+
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gtag.min.js"></script>
103119
```
104120

105121
## Emoji

src/plugins/ga.js

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,31 @@
11
/* eslint-disable no-console */
22
// From https://github.com/egoist/vue-ga/blob/master/src/index.js
3-
4-
function appendScript(id) {
3+
function appendScript() {
54
const script = document.createElement('script');
65
script.async = true;
7-
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + id;
6+
script.src = 'https://www.google-analytics.com/analytics.js';
87
document.body.appendChild(script);
98
}
109

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 ||
10+
function init(id) {
11+
appendScript();
12+
window.ga =
13+
window.ga ||
1814
function () {
19-
window.dataLayer.push(arguments);
15+
(window.ga.q = window.ga.q || []).push(arguments);
2016
};
2117

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-
}
18+
window.ga.l = Number(new Date());
19+
window.ga('create', id, 'auto');
4620
}
4721

4822
function collect() {
4923
if (!window.ga) {
5024
init($docsify.ga);
5125
}
5226

53-
// usage: https://developers.google.com/analytics/devguides/collection/gtagjs/pages
54-
window.gtag('event', 'page_view', {
55-
page_title: document.title,
56-
page_location: location.href,
57-
page_path: location.pathname,
58-
});
27+
window.ga('set', 'page', location.hash);
28+
window.ga('send', 'pageview');
5929
}
6030

6131
const install = function (hook) {

src/plugins/gtag.js

Lines changed: 72 additions & 0 deletions
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/ga.test.js renamed to test/e2e/gtag.test.js

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Modules, constants, and variables
2-
// npm run test:e2e ga.test.js
2+
// npm run test:e2e gtag.test.js
33
// -----------------------------------------------------------------------------
44
const docsifyInit = require('../helpers/docsify-init');
55
const { test, expect } = require('./fixtures/docsify-init-fixture');
66

7-
const gaTagList = [
7+
const gtagList = [
88
'AW-YYYYYY', // Google Ads
99
'DC-ZZZZZZ', // Floodlight
1010
'G-XXXXXX', // Google Analytics 4 (GA4)
@@ -13,14 +13,14 @@ const gaTagList = [
1313

1414
// Suite
1515
// -----------------------------------------------------------------------------
16-
test.describe('GA Plugin Tests', () => {
16+
test.describe('Gtag Plugin Tests', () => {
1717
// page request listened, print collect url
1818
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-
// });
19+
page.on('request', request => {
20+
if (request.url().indexOf('www.google-analytics.com') !== -1) {
21+
// console.log(request.url());
22+
}
23+
});
2424

2525
page.on('response', response => {
2626
const request = response.request();
@@ -30,7 +30,7 @@ test.describe('GA Plugin Tests', () => {
3030
const reg =
3131
/googleads\.g\.doubleclick\.net|www\.google-analytics\.com|www\.googletagmanager\.com/g;
3232
if (request.url().match(reg)) {
33-
console.log(request.url(), response.status());
33+
// console.log(request.url(), response.status());
3434
}
3535
});
3636
}
@@ -42,9 +42,9 @@ test.describe('GA Plugin Tests', () => {
4242

4343
const docsifyInitConfig = {
4444
config: {
45-
ga: gaTagList[0],
45+
gtag: gtagList[0],
4646
},
47-
scriptURLs: ['/lib/plugins/ga.min.js'],
47+
scriptURLs: ['/lib/plugins/gtag.min.js'],
4848
styleURLs: ['/lib/themes/vue.css'],
4949
};
5050

@@ -57,20 +57,20 @@ test.describe('GA Plugin Tests', () => {
5757
// Verify config options
5858
expect(typeof $docsify).toEqual('object');
5959

60-
console.log($docsify.ga, $docsify.ga === '');
60+
// console.log($docsify.gtag, $docsify.gtag === '');
6161

6262
// Tests
63-
expect($docsify.ga).not.toEqual('');
63+
expect($docsify.gtag).not.toEqual('');
6464
});
6565

6666
test('multi gtag', async ({ page }) => {
6767
pageRequestListened(page);
6868

6969
const docsifyInitConfig = {
7070
config: {
71-
ga: gaTagList,
71+
gtag: gtagList,
7272
},
73-
scriptURLs: ['/lib/plugins/ga.min.js'],
73+
scriptURLs: ['/lib/plugins/gtag.min.js'],
7474
styleURLs: ['/lib/themes/vue.css'],
7575
};
7676

@@ -83,10 +83,10 @@ test.describe('GA Plugin Tests', () => {
8383
// Verify config options
8484
expect(typeof $docsify).toEqual('object');
8585

86-
console.log($docsify.ga, $docsify.ga === '');
86+
// console.log($docsify.gtag, $docsify.gtag === '');
8787

8888
// Tests
89-
expect($docsify.ga).not.toEqual('');
89+
expect($docsify.gtag).not.toEqual('');
9090
});
9191

9292
test('data-ga attribute', async ({ page }) => {

0 commit comments

Comments
 (0)