Skip to content

Commit

Permalink
feat: add google analytics gtag.js plugin (#1702)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
5 people authored Jun 27, 2023
1 parent a8a25d0 commit 29f3c82
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 0 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
27 changes: 27 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ 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
Expand All @@ -91,6 +93,31 @@ Configure by `data-ga`.
<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 = {
gtag: [
'G-XXXXXXXX', // Google Analytics 4 (GA4)
'UA-XXXXXXXX', // Google Universal Analytics (GA3)
'AW-XXXXXXXX', // Google Ads
'DC-XXXXXXXX', // Floodlight
],
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gtag.min.js"></script>
```

## Emoji

Renders a larger collection of emoji shorthand codes. Without this plugin, Docsify is able to render only a limited number of emoji shorthand codes.
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);
97 changes: 97 additions & 0 deletions test/e2e/gtag.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Modules, constants, and variables
// npm run test:e2e gtag.test.js
// -----------------------------------------------------------------------------
const docsifyInit = require('../helpers/docsify-init');
const { test, expect } = require('./fixtures/docsify-init-fixture');

const gtagList = [
'AW-YYYYYY', // Google Ads
'DC-ZZZZZZ', // Floodlight
'G-XXXXXX', // Google Analytics 4 (GA4)
'UA-XXXXXX', // Google Universal Analytics (GA3)
];

// Suite
// -----------------------------------------------------------------------------
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('response', response => {
const request = response.request();
// googleads.g.doubleclick.net
// www.google-analytics.com
// www.googletagmanager.com
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());
}
});
}

// Tests
// ---------------------------------------------------------------------------
test('single gtag', async ({ page }) => {
pageRequestListened(page);

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

await docsifyInit({
...docsifyInitConfig,
});

const $docsify = await page.evaluate(() => window.$docsify);

// Verify config options
expect(typeof $docsify).toEqual('object');

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

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

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

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

await docsifyInit({
...docsifyInitConfig,
});

const $docsify = await page.evaluate(() => window.$docsify);

// Verify config options
expect(typeof $docsify).toEqual('object');

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

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

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

// TODO
});
});

1 comment on commit 29f3c82

@vercel
Copy link

@vercel vercel bot commented on 29f3c82 Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.