Skip to content

Commit 15b0de1

Browse files
authored
feat: add Google Analytics plugin (#12)
Also expose two new hooks for plugins. Also fix the waitBeforeTransition algorithm.
1 parent d4bad00 commit 15b0de1

File tree

31 files changed

+704
-104
lines changed

31 files changed

+704
-104
lines changed

examples/wordpress/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"react-dom": "^16.8.2",
1010
"smooth": "latest",
1111
"smooth-backend-wordpress": "latest",
12+
"smooth-plugin-google-analytics": "latest",
1213
"smooth-plugin-head-meta": "latest"
1314
},
1415
"resolutions": {

examples/wordpress/smooth.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import path from 'path'
33
module.exports = {
44
plugins: [
55
{ resolve: 'smooth-plugin-head-meta' },
6+
{
7+
resolve: 'smooth-plugin-google-analytics',
8+
options: {
9+
trackingId: 'YOUR_GOOGLE_ANALYTICS_TRACKING_ID',
10+
},
11+
},
612
{
713
resolve: 'smooth-backend-wordpress',
814
options: {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react'
2+
import { OutboundLink } from 'smooth-plugin-google-analytics'
3+
4+
export default function Hello() {
5+
return (
6+
<div>
7+
<OutboundLink href="https://www.google.com">Google</OutboundLink>
8+
</div>
9+
)
10+
}

examples/wordpress/src/pages/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ export default function Page({ title, book, specificBook, allBooks, blocks }) {
5656
</li>
5757
))}
5858
</ul>
59+
<Link waitBeforeTransition to="/hello">
60+
hello
61+
</Link>
5962
<Blocks blocks={blocks} />
6063
</div>
6164
)
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# smooth-plugin-google-analytics
2+
3+
Easily add Google Analytics to your Smooth site.
4+
5+
## Install
6+
7+
`npm install --save smooth-plugin-google-analytics`
8+
9+
## How to use
10+
11+
```javascript
12+
// In your smooth-config.js
13+
module.exports = {
14+
plugins: [
15+
{
16+
resolve: 'smooth-plugin-google-analytics',
17+
options: {
18+
trackingId: 'YOUR_GOOGLE_ANALYTICS_TRACKING_ID',
19+
// Puts tracking script in the head instead of the body
20+
head: false,
21+
// Setting this parameter is optional
22+
anonymize: true,
23+
// Setting this parameter is also optional
24+
respectDNT: true,
25+
// Avoids sending pageview hits from custom paths
26+
exclude: ['/preview/**', '/do-not-track/me/too/'],
27+
// Enables Google Optimize using your container Id
28+
optimizeId: 'YOUR_GOOGLE_OPTIMIZE_TRACKING_ID',
29+
// Enables Google Optimize Experiment ID
30+
experimentId: 'YOUR_GOOGLE_EXPERIMENT_ID',
31+
// Set Variation ID. 0 for original 1,2,3....
32+
variationId: 'YOUR_GOOGLE_OPTIMIZE_VARIATION_ID',
33+
// Any additional create only fields (optional)
34+
sampleRate: 5,
35+
siteSpeedSampleRate: 10,
36+
cookieDomain: 'example.com',
37+
},
38+
},
39+
],
40+
}
41+
```
42+
43+
See below for the complete list of [Create Only Fields](#create-only-fields).
44+
45+
## `<OutboundLink>` component
46+
47+
To make it easy to track clicks on outbound links in Google Analytics,
48+
the plugin provides a component.
49+
50+
To use it, simply import it and use it like you would the `<a>` element e.g.
51+
52+
```jsx
53+
import React from 'react'
54+
import { OutboundLink } from 'smooth-plugin-google-analytics'
55+
56+
export default function Main() {
57+
return (
58+
<div>
59+
<OutboundLink eventLabel="Google" href="https://www.google.com">
60+
Visit Google
61+
</OutboundLink>
62+
</div>
63+
)
64+
}
65+
```
66+
67+
## The "anonymize" option
68+
69+
Some countries (such as Germany) require you to use the
70+
[\_anonymizeIP](https://support.google.com/analytics/answer/2763052) function for
71+
Google Analytics. Otherwise you are not allowed to use it. The option adds two
72+
blocks to the code:
73+
74+
```javascript
75+
function gaOptout(){document.cookie=disableStr+'=true; expires=Thu, 31 Dec 2099 23:59:59 UTC;path=/',window[disableStr]=!0}var gaProperty='UA-XXXXXXXX-X',disableStr='ga-disable-'+gaProperty;document.cookie.indexOf(disableStr+'=true')>-1&&(window[disableStr]=!0);
76+
77+
...
78+
79+
ga('set', 'anonymizeIp', 1);
80+
```
81+
82+
If your visitors should be able to set an Opt-Out-Cookie (No future tracking)
83+
you can set a link e.g. in your imprint as follows:
84+
85+
`<a href="javascript:gaOptout();">Deactivate Google Analytics</a>`
86+
87+
## The "respectDNT" option
88+
89+
If you enable this optional option, Google Analytics will not be loaded at all for visitors that have "Do Not Track" enabled. While using Google Analytics does not necessarily constitute Tracking, you might still want to do this to cater to more privacy oriented users.
90+
91+
## The "exclude" option
92+
93+
If you need to exclude any path from the tracking system, you can add it (one or more) to this optional array as glob expressions.
94+
95+
## The "optimizeId" option
96+
97+
If you need to use Google Optimize for A/B testing, you can add this optional Optimize container id to allow Google Optimize to load the correct test parameters for your site.
98+
99+
## The "experimentId" option
100+
101+
If you need to set up SERVER_SIDE Google Optimize experiment, you can add the experiment ID. The experiment ID is shown on the right-hand panel on the experiment details page. [Server-side Experiments](https://developers.google.com/optimize/devguides/experiments)
102+
103+
## The "variationId" option
104+
105+
Besides the experiment ID you also need the variation ID for SERVER_SIDE experiments in Google Optimize. Set 0 for original version.
106+
107+
## Create Only Fields
108+
109+
This plugin supports all optional Create Only Fields documented in [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create):
110+
111+
- `name`: string, tracker name
112+
- `clientId`: string
113+
- `sampleRate`: number
114+
- `siteSpeedSampleRate`: number
115+
- `alwaysSendReferrer`: boolean
116+
- `allowAnchor`: boolean
117+
- `cookieName`: string
118+
- `cookieDomain`: string, defaults to `'auto'` if not given
119+
- `cookieExpires`: number
120+
- `storeGac`: boolean
121+
- `legacyCookieDomain`: string
122+
- `legacyHistoryImport`: boolean
123+
- `allowLinker`: boolean
124+
125+
These fields can be specified in the plugin's `options` as shown in the [How to use](#how-to-use) section.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/index')
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "smooth-plugin-google-analytics",
3+
"description": "Google Analytics plugin for Smooth.js",
4+
"version": "0.1.1-alpha.24",
5+
"repository": "https://github.com/smooth-code/smooth.js/tree/master/packages/smooth-plugin-google-analytics",
6+
"author": "Greg Bergé <berge.greg@gmail.com>",
7+
"publishConfig": {
8+
"access": "public"
9+
},
10+
"keywords": [
11+
"smooth-plugin"
12+
],
13+
"engines": {
14+
"node": ">=8"
15+
},
16+
"main": "index.js",
17+
"license": "MIT",
18+
"scripts": {
19+
"prebuild": "shx rm -rf lib",
20+
"build": "babel --root-mode upward -d lib --ignore \"**/*.test.js\" --copy-files src",
21+
"prepublishOnly": "yarn run build"
22+
},
23+
"peerDependencies": {
24+
"react": ">=16.8.0",
25+
"smooth": "^0.1.0"
26+
},
27+
"dependencies": {
28+
"graphql-tag": "^2.10.1",
29+
"minimatch": "^3.0.4"
30+
}
31+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/smooth-browser')
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/smooth-node')
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* eslint-env browser */
2+
import React, { useCallback } from 'react'
3+
4+
export function OutboundLink({ href, eventLabel, target, onClick, ...props }) {
5+
const handleClick = useCallback(
6+
event => {
7+
const sameTarget = target !== '_blank'
8+
const normalClick = !(
9+
event.ctrlKey ||
10+
event.shiftKey ||
11+
event.metaKey ||
12+
event.button === 1
13+
) // middleclick
14+
15+
if (sameTarget && normalClick) {
16+
event.preventDefault()
17+
window.ga('send', 'event', {
18+
eventCategory: 'Outbound Link',
19+
eventAction: 'click',
20+
eventLabel: eventLabel || href,
21+
hitCallback() {
22+
window.location.href = href
23+
},
24+
})
25+
} else {
26+
window.ga('send', 'event', {
27+
eventCategory: 'Outbound Link',
28+
eventAction: 'click',
29+
eventLabel: eventLabel || href,
30+
transport: 'beacon',
31+
})
32+
}
33+
34+
if (onClick) {
35+
onClick(event)
36+
}
37+
},
38+
[onClick, href, target, eventLabel],
39+
)
40+
41+
if (props.target === '_blank') {
42+
props.rel = 'noopener noreferrer'
43+
}
44+
45+
const rel =
46+
props.rel || (target === '_blank' ? 'noopener noreferrer' : undefined)
47+
return (
48+
<a href={href} onClick={handleClick} target={target} rel={rel} {...props} />
49+
)
50+
}

0 commit comments

Comments
 (0)