1 | const path = require('path')
|
2 |
|
3 | const defaults = {
|
4 | dev: true,
|
5 |
|
6 | id: null,
|
7 | layer: 'dataLayer',
|
8 | variables: {},
|
9 |
|
10 | pageTracking: false,
|
11 | pageViewEventName: 'nuxtRoute',
|
12 |
|
13 | autoInit: true,
|
14 | respectDoNotTrack: true,
|
15 |
|
16 | scriptId: 'gtm-script',
|
17 | scriptDefer: false,
|
18 | scriptURL: 'https://www.googletagmanager.com/gtm.js',
|
19 |
|
20 | noscript: false,
|
21 | noscriptId: 'gtm-noscript',
|
22 | noscriptURL: 'https://www.googletagmanager.com/ns.html'
|
23 | }
|
24 |
|
25 | module.exports = async function gtmModule (_options) {
|
26 | const options = {
|
27 | ...defaults,
|
28 | ..._options,
|
29 | ...this.options.gtm
|
30 | }
|
31 |
|
32 |
|
33 | if (this.options.dev && !options.dev) {
|
34 | return
|
35 | }
|
36 |
|
37 |
|
38 | if (!options.id) {
|
39 |
|
40 | console.warn('[@nuxtjs/gtm] Disabling module because no id is provided!')
|
41 | return
|
42 | }
|
43 |
|
44 |
|
45 | if (typeof (options.id) === 'function') {
|
46 | options.id = await options.id()
|
47 | }
|
48 |
|
49 |
|
50 | const query = {
|
51 | id: options.id,
|
52 |
|
53 | l: options.layer !== 'dataLayer' ? options.layer : null,
|
54 | ...options.variables
|
55 | }
|
56 | const queryString = Object.keys(query)
|
57 | .filter(key => query[key] !== null && query[key] !== undefined)
|
58 | .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
|
59 | .join('&')
|
60 |
|
61 |
|
62 |
|
63 | const dnt = "(function(w,n,d,m,e,p){w[d]=(w[d]==1||n[d]=='yes'||n[d]==1||n[m]==1||(w[e]&&w[e].p&&e[e][p]()))?1:0})(window,'navigator','doNotTrack','msDoNotTrack','external','msTrackingProtectionEnabled')"
|
64 |
|
65 |
|
66 |
|
67 | const initLayer = "w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'})"
|
68 |
|
69 | const injectScript = `var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.${options.scriptDefer ? 'defer' : 'async'}=true;j.src='${options.scriptURL + '?' + queryString}';f.parentNode.insertBefore(j,f);}`
|
70 |
|
71 | let script
|
72 | if (options.autoInit) {
|
73 | script = `(function(w,d,s,l){${initLayer};${injectScript})(window,document,'script','${options.layer}');`
|
74 | if (options.respectDoNotTrack) {
|
75 | script = `${dnt};window.doNotTrack||${script}`
|
76 | }
|
77 | } else {
|
78 | script = `${dnt};(function(w,l){${initLayer}})(window,'${options.layer}');window.$initGTM=function(){(function(d,s){${injectScript})(document,'script');}`
|
79 | }
|
80 |
|
81 |
|
82 | this.options.head.script = this.options.head.script || []
|
83 | this.options.head.script.push({
|
84 | hid: options.scriptId,
|
85 | innerHTML: script
|
86 | })
|
87 |
|
88 |
|
89 | if (options.noscript) {
|
90 | this.options.head.noscript = this.options.head.noscript || []
|
91 | this.options.head.noscript.push({
|
92 | hid: options.noscriptId,
|
93 | pbody: true,
|
94 | innerHTML: `<iframe src="${options.noscriptURL + '?' + queryString}" height="0" width="0" style="display:none;visibility:hidden" title="gtm"></iframe>`
|
95 | })
|
96 | }
|
97 |
|
98 |
|
99 | this.options.head.__dangerouslyDisableSanitizersByTagID = this.options.head.__dangerouslyDisableSanitizersByTagID || {}
|
100 | this.options.head.__dangerouslyDisableSanitizersByTagID[options.scriptId] = ['innerHTML']
|
101 | this.options.head.__dangerouslyDisableSanitizersByTagID[options.noscriptId] = ['innerHTML']
|
102 |
|
103 |
|
104 | this.addPlugin({
|
105 | src: path.resolve(__dirname, 'plugin.js'),
|
106 | fileName: 'gtm.js',
|
107 | ssr: false,
|
108 | options
|
109 | })
|
110 | }
|
111 |
|
112 | module.exports.meta = require('../package.json')
|