1 | const path = require('path')
|
2 | const defaults = require('./defaults')
|
3 |
|
4 |
|
5 |
|
6 | 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')"
|
7 |
|
8 | module.exports = async function gtmModule (_options) {
|
9 | const options = {
|
10 | ...defaults,
|
11 | ..._options,
|
12 | ...this.options.gtm
|
13 | }
|
14 |
|
15 |
|
16 | if (this.options.dev && !options.dev) {
|
17 | return
|
18 | }
|
19 |
|
20 |
|
21 | if (typeof (options.id) === 'function') {
|
22 | options.id = await options.id()
|
23 | }
|
24 |
|
25 |
|
26 | const query = {
|
27 |
|
28 | l: options.layer !== 'dataLayer' ? options.layer : null,
|
29 | ...options.variables
|
30 | }
|
31 | const queryString = Object.keys(query)
|
32 | .filter(key => query[key] !== null && query[key] !== undefined)
|
33 | .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
|
34 | .join('&')
|
35 |
|
36 |
|
37 | const initLayer = "w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'})"
|
38 |
|
39 | const injectScript = `var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.${options.scriptDefer ? 'defer' : 'async'}=true;j.src='${options.scriptURL + '?id=\'+i' + (queryString ? (`+'&${queryString}` + '\'') : '')};f.parentNode.insertBefore(j,f)`
|
40 |
|
41 | let script = `${initLayer};w[x]={};w._gtm_inject=function(i){if(w.doNotTrack||w[x][i])return;w[x][i]=1;${injectScript};}`
|
42 |
|
43 | if (options.autoInit) {
|
44 | if (options.id) {
|
45 | script += `;w[y]('${options.id}')`
|
46 | } else {
|
47 |
|
48 | console.warn('[@nuxtjs/gtm] `autoInit` set but no id provided!')
|
49 | }
|
50 | }
|
51 |
|
52 |
|
53 | script = `${dnt};(function(w,d,s,l,x,y){${script}})(window,document,'script','${options.layer}','_gtm_ids','_gtm_inject')`
|
54 |
|
55 |
|
56 | script = `if(!window._gtm_init){window._gtm_init=1;${script}}`
|
57 |
|
58 |
|
59 | this.options.head.script = this.options.head.script || []
|
60 | this.options.head.script.push({
|
61 | hid: options.scriptId,
|
62 | innerHTML: script
|
63 | })
|
64 |
|
65 |
|
66 | const renderIframe = id => `<iframe src="${options.noscriptURL + '?id=' + id + '&' + queryString}" height="0" width="0" style="display:none;visibility:hidden" title="gtm"></iframe>`
|
67 | if (options.noscript && options.id) {
|
68 | this.options.head.noscript = this.options.head.noscript || []
|
69 | this.options.head.noscript.push({
|
70 | hid: options.noscriptId,
|
71 | pbody: true,
|
72 | innerHTML: options.id ? renderIframe(options.id) : ''
|
73 | })
|
74 | }
|
75 |
|
76 |
|
77 | this.options.head.__dangerouslyDisableSanitizersByTagID = this.options.head.__dangerouslyDisableSanitizersByTagID || {}
|
78 | this.options.head.__dangerouslyDisableSanitizersByTagID[options.scriptId] = ['innerHTML']
|
79 | this.options.head.__dangerouslyDisableSanitizersByTagID[options.noscriptId] = ['innerHTML']
|
80 |
|
81 |
|
82 | this.addPlugin({
|
83 | src: path.resolve(__dirname, 'plugin.js'),
|
84 | fileName: 'gtm.js',
|
85 | options: {
|
86 | ...options,
|
87 | renderIframe
|
88 | }
|
89 | })
|
90 | }
|
91 |
|
92 | module.exports.meta = require('../package.json')
|