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

fix(gatsby-plugin-google-gtag): Add plugin options #37953

Merged
merged 6 commits into from
Apr 18, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
95 changes: 48 additions & 47 deletions packages/gatsby-plugin-google-gtag/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ For more general information on gtag you can read Google's official documentatio

If you're migrating from analytics.js (gatsby-plugin-google-analytics) you can read about the subtle API differences in more depth at: https://developers.google.com/analytics/devguides/migration/ua/analyticsjs-to-gtagjs.

**Please note:** This plugin only works in production mode! To test your Global Site Tag is installed and firing events correctly run: `gatsby build && gatsby serve.`
**Please note:** This plugin only works in production mode! To test that your Global Site Tag is installed and firing events correctly run: `gatsby build && gatsby serve.`

## Install

Expand All @@ -20,8 +20,9 @@ npm install gatsby-plugin-google-gtag

## How to use

```js
// In your gatsby-config.js
The `trackingIds` option is **required** for this plugin to work correctly.

```js:title=gatsby-config.js
module.exports = {
plugins: [
{
Expand Down Expand Up @@ -59,6 +60,50 @@ module.exports = {
}
```

### `gtagConfig.anonymize_ip` option

Some countries (such as Germany) require you to use the
[\_anonymizeIP](https://support.google.com/analytics/answer/2763052) function for
Google Site Tag. Otherwise you are not allowed to use it. The option adds the
block of code below:

```js
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)
```

If your visitors should be able to set an Opt-Out-Cookie (No future tracking)
you can set a link e.g. in your imprint as follows:

`<a href="javascript:gaOptout();">Deactivate Google Tracking</a>`

### `gtagConfig.optimize_id` option

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.

### Other `gtagConfig` options

The `gtagConfig` is passed directly to the gtag config command, so you can specify everything it supports, e.g. `gtagConfig.cookie_name`, `gtagConfig.sample_rate`. If you're migrating from the analytics.js plugin, this means that all Create Only Fields should be snake_cased.

### `pluginConfig.respectDNT` option

If you enable this optional option, Google Global Site Tag will not be loaded at all for visitors that have "Do Not Track" enabled. While using Google Global Site Tag does not necessarily constitute Tracking, you might still want to do this to cater to more privacy oriented users.

### `pluginConfig.exclude` option

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.

### `pluginConfig.delayOnRouteUpdate` option

If you need to delay processing pageview events on route update (e.g. to wait for page transitions with [`gatsby-plugin-transition-link`](https://www.gatsbyjs.com/plugins/gatsby-plugin-transition-link/)), then this option adds a delay before generating the pageview event.

## Custom Events

This plugin automatically sends a "pageview" event to all products given as "trackingIds" on every Gatsbys route change.
Expand Down Expand Up @@ -99,47 +144,3 @@ export default () => (
</div>
)
```

## The "gtagConfig.anonymize_ip" option

Some countries (such as Germany) require you to use the
[\_anonymizeIP](https://support.google.com/analytics/answer/2763052) function for
Google Site Tag. Otherwise you are not allowed to use it. The option adds the
block of code below:

```js
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)
```

If your visitors should be able to set an Opt-Out-Cookie (No future tracking)
you can set a link e.g. in your imprint as follows:

`<a href="javascript:gaOptout();">Deactivate Google Tracking</a>`

## The "gtagConfig.optimize_id" option

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.

## Other "gtagConfig" options

The `gtagConfig` is passed directly to the gtag config command, so you can specify everything it supports, e.g. `gtagConfig.cookie_name`, `gtagConfig.sample_rate`. If you're migrating from the analytics.js plugin, this means that all Create Only Fields should be snake_cased.

## The "pluginConfig.respectDNT" option

If you enable this optional option, Google Global Site Tag will not be loaded at all for visitors that have "Do Not Track" enabled. While using Google Global Site Tag does not necessarily constitute Tracking, you might still want to do this to cater to more privacy oriented users.

## The "pluginConfig.exclude" option

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.

## The "pluginConfig.delayOnRouteUpdate" option

If you need to delay processing pageview events on route update (e.g. to wait for page transitions with [`gatsby-plugin-transition-link`](https://www.gatsbyjs.com/plugins/gatsby-plugin-transition-link/)), then this option adds a delay before generating the pageview event.
3 changes: 2 additions & 1 deletion packages/gatsby-plugin-google-gtag/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"@babel/cli": "^7.20.7",
"@babel/core": "^7.20.12",
"babel-preset-gatsby-package": "^3.9.0-next.0",
"cross-env": "^7.0.3"
"cross-env": "^7.0.3",
"gatsby-plugin-utils": "^4.9.0-next.1"
},
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-google-gtag#readme",
"keywords": [
Expand Down
58 changes: 58 additions & 0 deletions packages/gatsby-plugin-google-gtag/src/__tests__/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { testPluginOptionsSchema } from "gatsby-plugin-utils"
import { pluginOptionsSchema } from "../gatsby-node"

describe(`pluginOptionsSchema`, () => {
it(`should invalidate incorrect options`, async () => {
const options = {
trackingIds: undefined, // Is required
gtagConfig: `test`,
pluginConfig: {
head: `test`,
respectDNT: `test`,
exclude: `test`,
origin: 1,
delayOnRouteUpdate: `test`,
},
}
const expectedErrors = [
`"trackingIds" is required`,
`"gtagConfig" must be of type object`,
`"pluginConfig.head" must be a boolean`,
`"pluginConfig.respectDNT" must be a boolean`,
`"pluginConfig.exclude" must be an array`,
`"pluginConfig.origin" must be a string`,
`"pluginConfig.delayOnRouteUpdate" must be a number`,
]

const { isValid, errors } = await testPluginOptionsSchema(
pluginOptionsSchema,
options
)

expect(isValid).toBe(false)
expect(errors).toEqual(expectedErrors)
})

it(`should validate correct options`, async () => {
const options = {
trackingIds: [`test`],
gtagConfig: {
anonymize_ip: true,
},
pluginConfig: {
head: true,
respectDNT: true,
exclude: [`test`],
origin: `test`,
delayOnRouteUpdate: 1,
},
}
const { isValid, errors } = await testPluginOptionsSchema(
pluginOptionsSchema,
options
)

expect(isValid).toBe(true)
expect(errors).toEqual([])
})
})
54 changes: 54 additions & 0 deletions packages/gatsby-plugin-google-gtag/src/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// @ts-check

/**
* @type {import('gatsby').GatsbyNode["pluginOptionsSchema"]}
*/
exports.pluginOptionsSchema = ({ Joi }) =>
Joi.object({
trackingIds: Joi.array()
.items(Joi.string())
.description(
`The tracking IDs; the tracking code won't be generated without them.`
)
.required(),
gtagConfig: Joi.object()
.keys({
optimize_id: Joi.string().description(
`Enable if you need to use Google Optimize.`
),
anonymize_ip: Joi.boolean()
.description(`Enable if you need to use the "anonymizeIP" function.`)
.default(false),
})
.unknown(true)
.description(
`This object gets passed directly to the gtag config command.`
)
.default({}),
pluginConfig: Joi.object()
.keys({
head: Joi.boolean()
.description(
`Puts tracking script in the <head> instead of the <body>`
)
.default(false),
respectDNT: Joi.boolean()
.description(
`If you enable this optional option, Google Global Site Tag will not be loaded at all for visitors that have "Do Not Track" enabled.`
)
.default(false),
exclude: Joi.array()
.items(Joi.string())
.description(
`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.`
)
.default([]),
origin: Joi.string()
.description(`Your optional self hosted origin for the script.`)
.default(`https://www.googletagmanager.com`),
delayOnRouteUpdate: Joi.number()
.description(`Delay processing pageview events on route update`)
.default(0),
})
.description(`Configure the plugin's behavior.`),
})