Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/issue 186 google analytics plugin #190

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion greenwood.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const googleAnalyticsPlugin = require('./packages/plugin-google-analytics/src/index');
const path = require('path');

const META_DESCRIPTION = 'A modern and performant static site generator supporting Web Component based development';
Expand All @@ -15,6 +16,12 @@ module.exports = {
{ property: 'og:image', content: 'https://s3.amazonaws.com/hosted.greenwoodjs.io/greenwood-logo.png' },
{ property: 'og:description', content: META_DESCRIPTION },
{ rel: 'shortcut icon', href: FAVICON_HREF },
{ rel: 'icon', href: FAVICON_HREF }
{ rel: 'icon', href: FAVICON_HREF },
{ name: 'google-site-verification', content: '4rYd8k5aFD0jDnN0CCFgUXNe4eakLP4NnA18mNnK5P0' }
],
plugins: [
...googleAnalyticsPlugin({
analyticsId: 'UA-147204327-1'
})
]
};
3 changes: 2 additions & 1 deletion nyc.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ module.exports = {
'packages/cli/src/lib/*.js',
'packages/cli/src/lifecycles/*.js',
'packages/cli/src/plugins/*.js',
'packages/cli/src/tasks/*.js'
'packages/cli/src/tasks/*.js',
'packages/plugin-*/src/*.js'
],

reporter: [
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
<!-- Error is a known issue: https://github.com/webcomponents/webcomponentsjs/issues/749 -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.0.2/custom-elements-es5-adapter.js"></script> -->

<%= htmlWebpackPlugin.options.hookAnalytics %>

<%= htmlWebpackPlugin.options.hookSpaIndexFallback %>
</head>

<body>

<eve-app></eve-app>

<%= htmlWebpackPlugin.options.hookAnalytics %>

<%= htmlWebpackPlugin.options.hookPolyfills %>

<!-- JavaScript polyfill FOR IE11 -->
Expand Down
43 changes: 43 additions & 0 deletions packages/plugin-google-analytics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# @greenwood/plugin-google-analytics

## Overview
A composite plugin for Greenwood for adding support for [Google Analytics](https://developers.google.com/analytics/) JavaScript tracker. For more information and complete docs about Greenwood, please visit the [Greenwood website](https://www.greenwoodjs.io/docs).

> This package assumes you already have `@greenwood/cli` installed.

## Installation
You can use your favorite JavaScript package manager to install this package.

_examples:_
```bash
# npm
npm -i @greenwood/plugin-google-analytics --save-dev

# yarn
yarn add @greenwood/plugin-google-analytics --dev
```

## Usage
Use this plugin in your _greenwood.config.js_ and simply pass in your Google Analytics ID, e.g. `UA-XXXXX`.

> As this is a composite plugin, you will need to spread the result.

```javascript
const googleAnalyticsPlugin = require('@greenwood/plugin-google-analytics');

module.exports = {
...

plugins: [
...googleAnalyticsPlugin({
analyticsId: 'UA-XXXXXX'
})
]
}
```

This will then add the Google Analytics [JavaScript tracker snippet](https://developers.google.com/analytics/devguides/collection/analyticsjs/) to your project's _index.html_.

### Options
- `analyticsId` (required) - Your Google Analytics ID
- `anonymous` (optional) - If tracking of IPs should be done anonymously. Defaults to `true`
18 changes: 18 additions & 0 deletions packages/plugin-google-analytics/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@greenwood/plugin-google-analytics",
"version": "0.3.6",
"description": "A composite plugin for Greenwood for adding support for Google Analytics.",
"repository": "https://github.com/ProjectEvergreen/greenwood/tree/master/packages/plugin-google-analytics",
"author": "Owen Buckley <[email protected]>",
"license": "MIT",
"main": "src/index.js",
"files": [
"src/"
],
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@greenwood/cli": "^0.3.6"
}
}
30 changes: 30 additions & 0 deletions packages/plugin-google-analytics/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = (options = {}) => {
const { analyticsId, anonymous } = options;

const validId = analyticsId && typeof analyticsId === 'string';
const trackAnon = typeof anonymous === 'boolean' ? anonymous : true;

if (!validId) {
throw new Error(`Error: analyticsId should be of type string. get "${typeof analyticsId}" instead.`);
}

return [{
type: 'index',
provider: () => {
return {
hookAnalytics: `
<script async src="https://www.googletagmanager.com/gtag/js?id=${analyticsId}"></script>

<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());

gtag('config', '${analyticsId}', { 'anonymize_ip': ${trackAnon} });
gtag('config', '${analyticsId}');
</script>
`
};
}
}];
};
109 changes: 109 additions & 0 deletions packages/plugin-google-analytics/test/cases/default/default.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Use Case
* Run Greenwood with Google Analytics composite plugin with default options.
*
* Uaer Result
* Should generate a bare bones Greenwood build with certain plugins injected into index.html.
*
* User Command
* greenwood build
*
* User Config
* const googleAnalyticsPlugin = require('@greenwod/plugin-google-analytics');
*
* {
* plugins: [{
* ...googleAnalyticsPlugin({
* analyticsId: 'UA-123456-1'
* })
* }]
*
* }
*
* User Workspace
* Greenwood default (src/)
*/
const expect = require('chai').expect;
const { JSDOM } = require('jsdom');
const path = require('path');
const runSmokeTest = require('../../../../../test/smoke-test');
const TestBed = require('../../../../../test/test-bed');

describe('Build Greenwood With: ', async function() {
const LABEL = 'Google Analytics Plugin with default options and Default Workspace';
const mockAnalyticsId = 'UA-123456-1';

let setup;

before(async function() {
setup = new TestBed();
this.context = setup.setupTestBed(__dirname);
});

describe(LABEL, function() {
before(async function() {
await setup.runGreenwoodCommand('build');
});

runSmokeTest(['public', 'index', 'not-found', 'hello'], LABEL);

describe('Initialization script at the end of the <body> tag', function() {
let inlineScript;

beforeEach(async function() {
const dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, 'index.html'));
const scriptTags = dom.window.document.querySelectorAll('head script');

inlineScript = Array.prototype.slice.call(scriptTags).filter(script => {
return !script.src;
});

});

it('should be one inline <script> tag', function() {
expect(inlineScript.length).to.be.equal(1);
});

it('should have the expected code with users analyicsId', function() {
const expectedContent = `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());

gtag('config', '${mockAnalyticsId}', { 'anonymize_ip': true });
gtag('config', '${mockAnalyticsId}');
`;

expect(inlineScript[0].textContent).to.contain(expectedContent);
});
});

describe('Tracking script at the end of the <body> tag', function() {
let trackingScript;

beforeEach(async function() {
const dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, 'index.html'));
const scriptTags = dom.window.document.querySelectorAll('head script');

trackingScript = Array.prototype.slice.call(scriptTags).filter(script => {
return script.src === `https://www.googletagmanager.com/gtag/js?id=${mockAnalyticsId}`;
});
});

it('should have one <script> tag for loading the Google Analytics tracker', function() {
expect(trackingScript.length).to.be.equal(1);
});

it('should be an async <script> tag for loading the Google Analytics tracker', function() {
const isAsync = trackingScript[0].async !== null;

expect(isAsync).to.be.equal(true);
});
});
});

after(function() {
setup.teardownTestBed();
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const googleAnalyticsPlugin = require('../../../src/index');

module.exports = {
plugins: [
...googleAnalyticsPlugin({
analyticsId: 'UA-123456-1'
})
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Use Case
* Run Greenwood with Google Analytics composite plugin.
*
* Uaer Result
* Should generate an error when not passing in a valid analyticsId.
*
* User Command
* greenwood build
*
* User Config
* const googleAnalyticsPlugin = require('@greenwod/plugin-google-analytics');
*
* {
* plugins: [{
* ...googleAnalyticsPlugin()
* }]
*
* }
*
* User Workspace
* Greenwood default (src/)
*/
const expect = require('chai').expect;
const TestBed = require('../../../../../test/test-bed');

describe('Build Greenwood With: ', async function() {
let setup;

before(async function() {
setup = new TestBed();
this.context = setup.setupTestBed(__dirname);
});

describe('Google Analytics Plugin with a bad value for analyticsId', () => {
it('should throw an error that analyticsId must be a string', async () => {
try {
await setup.runGreenwoodCommand('build');
} catch (err) {
expect(err).to.contain('analyticsId should be of type string. get "undefined" instead.');
}
});
});

after(function() {
setup.teardownTestBed();
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const googleAnalyticsPlugin = require('../../../src/index');

module.exports = {
plugins: [
...googleAnalyticsPlugin()
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const googleAnalyticsPlugin = require('../../../src/index');

module.exports = {
plugins: [
...googleAnalyticsPlugin({
analyticsId: 'UA-123456-1',
anonymous: false
})
]
};
Loading