From f33275925d01ad07bd0dd7d3d2b09e289732fd88 Mon Sep 17 00:00:00 2001 From: Eljas Jalo Date: Mon, 1 Feb 2021 16:34:12 +0200 Subject: [PATCH 1/6] Added tag manager integration --- lib/module.js | 2 ++ lib/plugin.js | 28 +++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/module.js b/lib/module.js index 76abe2c..c804843 100644 --- a/lib/module.js +++ b/lib/module.js @@ -7,6 +7,8 @@ module.exports = async function module (moduleOptions) { experimentsDir: '~/experiments', maxAge: 60 * 60 * 24 * 7, // 1 Week plugins: [], + eventHandler: 'ga', + dataLayer: 'dataLayer', excludeBots: true, botExpression: /(bot|spider|crawler)/i }, diff --git a/lib/plugin.js b/lib/plugin.js index 0ff8eac..18de377 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -120,14 +120,32 @@ function setCookie(ctx, name, value, maxAge = <%= options.maxAge %>) { } // https://developers.google.com/optimize/devguides/experiments -function googleOptimize({ experiment }) { - if (process.server || !window.ga || !experiment || !experiment.experimentID) { +function googleOptimize(ctx) { + const { experiment } = ctx + if (process.server || !experiment || !experiment.experimentID) { return } - const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') - - window.ga('set', 'exp', exp) + // Choose method to track experiment and variant + <% if (options.eventHandler === 'ga') { %> + // Use Google Analytics integration + // https://developers.google.com/optimize/devguides/experiments + const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') + if (!window.ga) return + window.ga('set', 'exp', exp) + <% } else if (options.eventHandler === 'gtm') { %> + // Use @nuxtjs/gtm-module + if (!ctx.$gtm) return + ctx.$gtm.push({ + exp: exp + }) + <% } else if (options.eventHandler === 'dataLayer') { %> + // Use other tag manager integration + if (!window[options.dataLayer]) return + window[options.dataLayer].push({ + exp: exp + }) + <% } %> } // should we skip bots? From 7aa3734674d3596ccc9f6d04cab0b367486be2ca Mon Sep 17 00:00:00 2001 From: Eljas Jalo Date: Mon, 1 Feb 2021 16:34:42 +0200 Subject: [PATCH 2/6] Update documentation with GTM integration --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 92ace75..9a06b1f 100755 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ npm install nuxt-google-optimize --save // experimentsDir: '~/experiments', // maxAge: 60 * 60 * 24 * 7 // 1 Week // pushPlugin: true, + // eventHandler: 'ga', // 'ga' = Google Analytics integration || 'gtm' = @nuxtjs/gtm-module integration || 'dataLayer' = GTM integration + // dataLayer: 'dataLayer', // eventHandler option has to be 'dataLayer' when implementing custom GTM dataLayer // excludeBots: true, // botExpression: /(bot|spider|crawler)/i } @@ -222,6 +224,22 @@ import './styles.scss' } ``` +## Usage with GTM + +- Set `options.eventHandler` to 'gtm' or 'dataLayer' depending which integration style you use for Tag Manager. +- Edit your "Page view (Google Analytics)" -tag in [Google Tag Manager](https://tagmanager.google.com/#/home) + - Add new "Fields to Set": + - Field Name: exp + - Value: {{googleOptimizeExp}} +- Add new Data Layer Variable called "googleOptimizeExp" as defined above. + - Variable type: Data Layer Variable + - Data Layer Variable Name: exp + +[Source for this setup lossleader's answer in StackOverflow](https://stackoverflow.com/a/53253769/871677) + +Now this module pushes experiment id and variable number to Google Analytics via Google Tag Manager. +experiment.experimentID + '.' + experiment.$variantIndexes.join('-') + ## Development - Clone this repository From 4006727596a31f9c578276950bd2997b602407e4 Mon Sep 17 00:00:00 2001 From: Eljas Jalo Date: Tue, 2 Feb 2021 13:14:00 +0200 Subject: [PATCH 3/6] Add docs of possible options with current defaults --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a06b1f..ea2d562 100755 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ npm install nuxt-google-optimize --save // experimentsDir: '~/experiments', // maxAge: 60 * 60 * 24 * 7 // 1 Week // pushPlugin: true, - // eventHandler: 'ga', // 'ga' = Google Analytics integration || 'gtm' = @nuxtjs/gtm-module integration || 'dataLayer' = GTM integration + // eventHandler: 'ga', // 'ga' (default) = Google Analytics integration || 'gtm' = @nuxtjs/gtm-module integration || 'dataLayer' = GTM integration // dataLayer: 'dataLayer', // eventHandler option has to be 'dataLayer' when implementing custom GTM dataLayer // excludeBots: true, // botExpression: /(bot|spider|crawler)/i From 711ff583e10f5e2b48bb12702e5abce0315da7d7 Mon Sep 17 00:00:00 2001 From: Eljas Jalo Date: Tue, 2 Feb 2021 13:17:28 +0200 Subject: [PATCH 4/6] Use shorthands and set "ga" to be default --- lib/plugin.js | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/lib/plugin.js b/lib/plugin.js index 18de377..2f1f876 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -120,31 +120,26 @@ function setCookie(ctx, name, value, maxAge = <%= options.maxAge %>) { } // https://developers.google.com/optimize/devguides/experiments -function googleOptimize(ctx) { - const { experiment } = ctx - if (process.server || !experiment || !experiment.experimentID) { - return - } +function googleOptimize({ experiment, $gtm }) { + if (process.server || !experiment || !experiment.experimentID) return + + const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') // Choose method to track experiment and variant - <% if (options.eventHandler === 'ga') { %> - // Use Google Analytics integration - // https://developers.google.com/optimize/devguides/experiments - const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') - if (!window.ga) return - window.ga('set', 'exp', exp) - <% } else if (options.eventHandler === 'gtm') { %> + <% if (options.eventHandler === 'gtm') { %> // Use @nuxtjs/gtm-module - if (!ctx.$gtm) return - ctx.$gtm.push({ - exp: exp - }) - <% } else if (options.eventHandler === 'dataLayer') { %> + if (!$gtm) return + $gtm.push({ exp }) + <% } else if (options.eventHandler === 'dataLayer') { %> // Use other tag manager integration - if (!window[options.dataLayer]) return - window[options.dataLayer].push({ - exp: exp - }) + const gtmDataLayer = window[<%= options.dataLayer %>] + if (!gtmDataLayer) return + gtmDataLayer.push({ exp }) + <% } else { %> + // Default: use Google Analytics integration + const { ga } = window + if (!ga) return + ga('set', 'exp', exp) <% } %> } From cf2aa633464cda1987863e83aa5b3c185cdab3d1 Mon Sep 17 00:00:00 2001 From: Eljas Jalo Date: Thu, 4 Feb 2021 12:40:42 +0200 Subject: [PATCH 5/6] Update usage example and default options --- README.md | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ea2d562..49d2831 100755 --- a/README.md +++ b/README.md @@ -41,17 +41,71 @@ npm install nuxt-google-optimize --save // Optional options googleOptimize: { - // experimentsDir: '~/experiments', - // maxAge: 60 * 60 * 24 * 7 // 1 Week - // pushPlugin: true, - // eventHandler: 'ga', // 'ga' (default) = Google Analytics integration || 'gtm' = @nuxtjs/gtm-module integration || 'dataLayer' = GTM integration - // dataLayer: 'dataLayer', // eventHandler option has to be 'dataLayer' when implementing custom GTM dataLayer - // excludeBots: true, - // botExpression: /(bot|spider|crawler)/i + /* module options */ } } ``` +## Options + +### `experimentsDir` + +- Type: `String` +- Default: `'~/experiments'` + +Provide path where experiments are located. + +### `maxAge` + +- Type: `Number` +- Default: `60 * 60 * 24 * 7` + +Provides default max age for user to test. + +### `pushPlugin` + +- Type: `Boolean` +- Default: `true` + +### `eventHandler` + +- Type: `Function` +- Default: +```js +(experiment, context) => { + const exp = + experiment.experimentID + '.' + experiment.$variantIndexes.join('-') + const { ga } = window + if (!ga) return + ga('set', 'exp', exp) +} +``` + +Provide custom event handler to send experiment details. + +Usage example: +```js +googleOptimize: { + eventHandler: (experiment, context) => { + const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') + const { ga } = window + if (!ga) return + ga('set', 'exp', exp) + } +} +``` + +### `excludeBots` + +- Type: `Boolean` +- Default: `true` + +### `botExpression` + +- Type: `RegExp` +- Default: `/(bot|spider|crawler)/i` + + ## Usage Create `experiments` directory inside your project. @@ -226,7 +280,26 @@ import './styles.scss' ## Usage with GTM -- Set `options.eventHandler` to 'gtm' or 'dataLayer' depending which integration style you use for Tag Manager. +- Set `options.eventHandler`: +```js +// GTM module +{ + eventHandler: (experiment, { $gtm }) => { + const exp = `${experiment.experimentID}.${experiment.$variantIndexes.join( '-' )}` + $gtm.push({ exp }) + } +} + +// Default datalayer +{ + eventHandler: (experiment, { $gtm }) => { + const exp = `${experiment.experimentID}.${experiment.$variantIndexes.join( '-' )}` + const { dataLayer } = window + if (!dataLayer) return + dataLayer.push({ exp }) + } +} +``` - Edit your "Page view (Google Analytics)" -tag in [Google Tag Manager](https://tagmanager.google.com/#/home) - Add new "Fields to Set": - Field Name: exp @@ -235,6 +308,7 @@ import './styles.scss' - Variable type: Data Layer Variable - Data Layer Variable Name: exp + [Source for this setup lossleader's answer in StackOverflow](https://stackoverflow.com/a/53253769/871677) Now this module pushes experiment id and variable number to Google Analytics via Google Tag Manager. From c873d9cb29e3804ed3cc2b001aa54b5d7b6ecaa9 Mon Sep 17 00:00:00 2001 From: Eljas Jalo Date: Thu, 4 Feb 2021 12:42:00 +0200 Subject: [PATCH 6/6] Change eventHandler to support different tracking methods --- lib/module.js | 8 ++++++-- lib/plugin.js | 23 ++++------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/lib/module.js b/lib/module.js index c804843..118891d 100644 --- a/lib/module.js +++ b/lib/module.js @@ -7,8 +7,12 @@ module.exports = async function module (moduleOptions) { experimentsDir: '~/experiments', maxAge: 60 * 60 * 24 * 7, // 1 Week plugins: [], - eventHandler: 'ga', - dataLayer: 'dataLayer', + eventHandler: (experiment, context) => { + const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') + const { ga } = window + if (!ga) return + ga('set', 'exp', exp) + }, excludeBots: true, botExpression: /(bot|spider|crawler)/i }, diff --git a/lib/plugin.js b/lib/plugin.js index 2f1f876..75e2fea 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -120,27 +120,12 @@ function setCookie(ctx, name, value, maxAge = <%= options.maxAge %>) { } // https://developers.google.com/optimize/devguides/experiments -function googleOptimize({ experiment, $gtm }) { +function googleOptimize(ctx) { + const { experiment } = ctx if (process.server || !experiment || !experiment.experimentID) return - const exp = experiment.experimentID + '.' + experiment.$variantIndexes.join('-') - - // Choose method to track experiment and variant - <% if (options.eventHandler === 'gtm') { %> - // Use @nuxtjs/gtm-module - if (!$gtm) return - $gtm.push({ exp }) - <% } else if (options.eventHandler === 'dataLayer') { %> - // Use other tag manager integration - const gtmDataLayer = window[<%= options.dataLayer %>] - if (!gtmDataLayer) return - gtmDataLayer.push({ exp }) - <% } else { %> - // Default: use Google Analytics integration - const { ga } = window - if (!ga) return - ga('set', 'exp', exp) - <% } %> + const handler = <%= serializeFunction(options.eventHandler) %> + handler(experiment, ctx) } // should we skip bots?