Skip to content

Commit

Permalink
feat: add Google Analytics 4 (GA4) gtag.js plugin (docsifyjs#1695)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhanzhao committed Aug 2, 2022
1 parent 6a3bd84 commit 9a854ec
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 69 deletions.
1 change: 1 addition & 0 deletions build/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ async function buildAllPlugin() {
var plugins = [
{name: 'search', input: 'search/index.js'},
{name: 'ga', input: 'ga.js'},
{name: 'gtag', input: 'gtag.js'},
{name: 'matomo', input: 'matomo.js'},
{name: 'emoji', input: 'emoji.js'},
{name: 'external-script', input: 'external-script.js'},
Expand Down
38 changes: 27 additions & 11 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,42 @@ This plugin ignores diacritical marks when performing a full text search (e.g.,

## Google Analytics

> 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.
Install the plugin and configure the track id.

```html
<script>
// Single ID
window.$docsify = {
ga: 'UA-XXXXX-Y',
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
```

Configure by `data-ga`.

<!-- prettier-ignore -->
```html
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js" data-ga="UA-XXXXX-Y"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
```

## Google Analytics 4 (GA4)

Install the plugin and configure the track id.

```html
<script>
// Single ID
window.$docsify = {
gtag: 'UA-XXXXX-Y',
};
// Multiple IDs
window.$docsify = {
ga: [
gtag: [
'G-XXXXXXXX', // Google Analytics 4 (GA4)
'UA-XXXXXXXX', // Google Universal Analytics (GA3)
'AW-XXXXXXXX', // Google Ads
Expand All @@ -91,15 +115,7 @@ Install the plugin and configure the track id.
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
```

Configure by `data-ga`, only support single gtag.

<!-- prettier-ignore -->
```html
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js" data-ga="UA-XXXXX-Y"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gtag.min.js"></script>
```

## Emoji
Expand Down
52 changes: 11 additions & 41 deletions src/plugins/ga.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,31 @@
/* eslint-disable no-console */
// From https://github.com/egoist/vue-ga/blob/master/src/index.js

function appendScript(id) {
function appendScript() {
const script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + id;
script.src = 'https://www.google-analytics.com/analytics.js';
document.body.appendChild(script);
}

// global site tag instance initialized
function initGlobalSiteTag(id) {
appendScript(id);

window.dataLayer = window.dataLayer || [];
window.gtag =
window.gtag ||
function init(id) {
appendScript();
window.ga =
window.ga ||
function () {
window.dataLayer.push(arguments);
(window.ga.q = window.ga.q || []).push(arguments);
};

window.gtag('js', new Date());
window.gtag('config', id);
}

// add additional products to your tag
// https://developers.google.com/tag-platform/gtagjs/install
function initAdditionalTag(id) {
window.gtag('config', id);
}

function init(ids) {
if (Array.isArray(ids)) {
// set the first id to be a global site tag
initGlobalSiteTag(ids[0]);

// the rest ids
ids.forEach((id, index) => {
if (index > 0) {
initAdditionalTag(id);
}
});
} else {
initGlobalSiteTag(ids);
}
window.ga.l = Number(new Date());
window.ga('create', id, 'auto');
}

function collect() {
if (!window.ga) {
init($docsify.ga);
}

// usage: https://developers.google.com/analytics/devguides/collection/gtagjs/pages
window.gtag('event', 'page_view', {
page_title: document.title,
page_location: location.href,
page_path: location.pathname,
});
window.ga('set', 'page', location.hash);
window.ga('send', 'pageview');
}

const install = function (hook) {
Expand Down
72 changes: 72 additions & 0 deletions src/plugins/gtag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* eslint-disable no-console */
// From ./ga.js

function appendScript(id) {
const script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + id;
document.body.appendChild(script);
}

// global site tag instance initialized
function initGlobalSiteTag(id) {
appendScript(id);

window.dataLayer = window.dataLayer || [];
window.gtag =
window.gtag ||
function () {
window.dataLayer.push(arguments);
};

window.gtag('js', new Date());
window.gtag('config', id);
}

// add additional products to your tag
// https://developers.google.com/tag-platform/gtagjs/install
function initAdditionalTag(id) {
window.gtag('config', id);
}

function init(ids) {
if (Array.isArray(ids)) {
// set the first id to be a global site tag
initGlobalSiteTag(ids[0]);

// the rest ids
ids.forEach((id, index) => {
if (index > 0) {
initAdditionalTag(id);
}
});
} else {
initGlobalSiteTag(ids);
}
}

function collect() {
if (!window.gtag) {
init($docsify.gtag);
}

// usage: https://developers.google.com/analytics/devguides/collection/gtagjs/pages
window.gtag('event', 'page_view', {
/* eslint-disable camelcase */
page_title: document.title,
page_location: location.href,
page_path: location.pathname,
/* eslint-disable camelcase */
});
}

const install = function (hook) {
if (!$docsify.gtag) {
console.error('[Docsify] gtag is required.');
return;
}

hook.beforeEach(collect);
};

$docsify.plugins = [].concat(install, $docsify.plugins);
34 changes: 17 additions & 17 deletions test/e2e/ga.test.js → test/e2e/gtag.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Modules, constants, and variables
// npm run test:e2e ga.test.js
// npm run test:e2e gtag.test.js
// -----------------------------------------------------------------------------
const docsifyInit = require('../helpers/docsify-init');
const { test, expect } = require('./fixtures/docsify-init-fixture');

const gaTagList = [
const gtagList = [
'AW-YYYYYY', // Google Ads
'DC-ZZZZZZ', // Floodlight
'G-XXXXXX', // Google Analytics 4 (GA4)
Expand All @@ -13,14 +13,14 @@ const gaTagList = [

// Suite
// -----------------------------------------------------------------------------
test.describe('GA Plugin Tests', () => {
test.describe('Gtag Plugin Tests', () => {
// page request listened, print collect url
function pageRequestListened(page) {
// page.on('request', request => {
// if (request.url().indexOf('www.google-analytics.com') !== -1) {
// console.log(request.url());
// }
// });
page.on('request', request => {
if (request.url().indexOf('www.google-analytics.com') !== -1) {
// console.log(request.url());
}
});

page.on('response', response => {
const request = response.request();
Expand All @@ -30,7 +30,7 @@ test.describe('GA Plugin Tests', () => {
const reg =
/googleads\.g\.doubleclick\.net|www\.google-analytics\.com|www\.googletagmanager\.com/g;
if (request.url().match(reg)) {
console.log(request.url(), response.status());
// console.log(request.url(), response.status());
}
});
}
Expand All @@ -42,9 +42,9 @@ test.describe('GA Plugin Tests', () => {

const docsifyInitConfig = {
config: {
ga: gaTagList[0],
gtag: gtagList[0],
},
scriptURLs: ['/lib/plugins/ga.min.js'],
scriptURLs: ['/lib/plugins/gtag.min.js'],
styleURLs: ['/lib/themes/vue.css'],
};

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

console.log($docsify.ga, $docsify.ga === '');
// console.log($docsify.gtag, $docsify.gtag === '');

// Tests
expect($docsify.ga).not.toEqual('');
expect($docsify.gtag).not.toEqual('');
});

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

const docsifyInitConfig = {
config: {
ga: gaTagList,
gtag: gtagList,
},
scriptURLs: ['/lib/plugins/ga.min.js'],
scriptURLs: ['/lib/plugins/gtag.min.js'],
styleURLs: ['/lib/themes/vue.css'],
};

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

console.log($docsify.ga, $docsify.ga === '');
// console.log($docsify.gtag, $docsify.gtag === '');

// Tests
expect($docsify.ga).not.toEqual('');
expect($docsify.gtag).not.toEqual('');
});

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

0 comments on commit 9a854ec

Please sign in to comment.