feat: analytics code rendering
This commit is contained in:
		| @@ -44,6 +44,7 @@ module.exports = { | ||||
|               return result | ||||
|             }, {}) | ||||
|           }).where('key', str.key) | ||||
|           await WIKI.cache.del('analytics') | ||||
|         } | ||||
|         return { | ||||
|           responseResult: graphHelper.generateSuccess('Providers updated successfully') | ||||
|   | ||||
| @@ -153,6 +153,7 @@ module.exports = async () => { | ||||
|       company: WIKI.config.company | ||||
|     } | ||||
|     res.locals.langs = await WIKI.models.locales.getNavLocales({ cache: true }) | ||||
|     res.locals.analyticsCode = await WIKI.models.analytics.getCode({ cache: true }) | ||||
|     next() | ||||
|   }) | ||||
|  | ||||
|   | ||||
| @@ -93,4 +93,51 @@ module.exports = class Analytics extends Model { | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static async getCode ({ cache = false } = {}) { | ||||
|     if (cache) { | ||||
|       const analyticsCached = await WIKI.cache.get('analytics') | ||||
|       if (analyticsCached) { | ||||
|         return analyticsCached | ||||
|       } | ||||
|     } | ||||
|     try { | ||||
|       const analyticsCode = { | ||||
|         head: '', | ||||
|         bodyStart: '', | ||||
|         bodyEnd: '' | ||||
|       } | ||||
|       const providers = await WIKI.models.analytics.getProviders(true) | ||||
|  | ||||
|       for (let provider of providers) { | ||||
|         const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/analytics', provider.key, 'code.yml'), 'utf8') | ||||
|         let code = yaml.safeLoad(def) | ||||
|         code.head = _.defaultTo(code.head, '') | ||||
|         code.bodyStart = _.defaultTo(code.bodyStart, '') | ||||
|         code.bodyEnd = _.defaultTo(code.bodyEnd, '') | ||||
|  | ||||
|         _.forOwn(provider.config, (value, key) => { | ||||
|           code.head = _.replace(code.head, `{{${key}}}`, value) | ||||
|           code.bodyStart = _.replace(code.bodyStart, `{{${key}}}`, value) | ||||
|           code.bodyEnd = _.replace(code.bodyEnd, `{{${key}}}`, value) | ||||
|         }) | ||||
|  | ||||
|         analyticsCode.head += code.head | ||||
|         analyticsCode.bodyStart += code.bodyStart | ||||
|         analyticsCode.bodyEnd += code.bodyEnd | ||||
|       } | ||||
|  | ||||
|       await WIKI.cache.set('analytics', analyticsCode, 300) | ||||
|  | ||||
|       return analyticsCode | ||||
|     } catch (err) { | ||||
|       WIKI.logger.warn('Error while getting analytics code: ', err) | ||||
|       return { | ||||
|         head: '', | ||||
|         bodyStart: '', | ||||
|         bodyEnd: '' | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								server/modules/analytics/azureinsights/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								server/modules/analytics/azureinsights/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| head: | | ||||
|   <script type="text/javascript"> | ||||
|     var sdkInstance="appInsightsSDK";window[sdkInstance]="appInsights";var aiName=window[sdkInstance],aisdk=window[aiName]||function(e){ | ||||
|       function n(e){t[e]=function(){var n=arguments;t.queue.push(function(){t[e].apply(t,n)})}}var t={config:e};t.initialize=!0;var i=document,a=window;setTimeout(function(){var n=i.createElement("script");n.src=e.url||"https://az416426.vo.msecnd.net/next/ai.2.min.js",i.getElementsByTagName("script")[0].parentNode.appendChild(n)});try{t.cookie=i.cookie}catch(e){}t.queue=[],t.version=2;for(var r=["Event","PageView","Exception","Trace","DependencyData","Metric","PageViewPerformance"];r.length;)n("track"+r.pop());n("startTrackPage"),n("stopTrackPage");var s="Track"+r[0];if(n("start"+s),n("stop"+s),n("setAuthenticatedUserContext"),n("clearAuthenticatedUserContext"),n("flush"),!(!0===e.disableExceptionTracking||e.extensionConfig&&e.extensionConfig.ApplicationInsightsAnalytics&&!0===e.extensionConfig.ApplicationInsightsAnalytics.disableExceptionTracking)){n("_"+(r="onerror"));var o=a[r];a[r]=function(e,n,i,a,s){var c=o&&o(e,n,i,a,s);return!0!==c&&t["_"+r]({message:e,url:n,lineNumber:i,columnNumber:a,error:s}),c},e.autoExceptionInstrumented=!0}return t | ||||
|     }({ | ||||
|       instrumentationKey:"{{instrumentationKey}}" | ||||
|     }); | ||||
|  | ||||
|     window[aiName]=aisdk,aisdk.queue&&0===aisdk.queue.length&&aisdk.trackPageView({}); | ||||
|   </script> | ||||
| @@ -11,13 +11,3 @@ props: | ||||
|     title: Instrumentation Key | ||||
|     hint: Found in the Azure Portal in your Application Insights resource panel | ||||
|     order: 1 | ||||
| codeHead: | | ||||
|   <script type="text/javascript"> | ||||
|     var sdkInstance="appInsightsSDK";window[sdkInstance]="appInsights";var aiName=window[sdkInstance],aisdk=window[aiName]||function(e){ | ||||
|       function n(e){t[e]=function(){var n=arguments;t.queue.push(function(){t[e].apply(t,n)})}}var t={config:e};t.initialize=!0;var i=document,a=window;setTimeout(function(){var n=i.createElement("script");n.src=e.url||"https://az416426.vo.msecnd.net/next/ai.2.min.js",i.getElementsByTagName("script")[0].parentNode.appendChild(n)});try{t.cookie=i.cookie}catch(e){}t.queue=[],t.version=2;for(var r=["Event","PageView","Exception","Trace","DependencyData","Metric","PageViewPerformance"];r.length;)n("track"+r.pop());n("startTrackPage"),n("stopTrackPage");var s="Track"+r[0];if(n("start"+s),n("stop"+s),n("setAuthenticatedUserContext"),n("clearAuthenticatedUserContext"),n("flush"),!(!0===e.disableExceptionTracking||e.extensionConfig&&e.extensionConfig.ApplicationInsightsAnalytics&&!0===e.extensionConfig.ApplicationInsightsAnalytics.disableExceptionTracking)){n("_"+(r="onerror"));var o=a[r];a[r]=function(e,n,i,a,s){var c=o&&o(e,n,i,a,s);return!0!==c&&t["_"+r]({message:e,url:n,lineNumber:i,columnNumber:a,error:s}),c},e.autoExceptionInstrumented=!0}return t | ||||
|     }({ | ||||
|       instrumentationKey:"{{instrumentationKey}}" | ||||
|     }); | ||||
|  | ||||
|     window[aiName]=aisdk,aisdk.queue&&0===aisdk.queue.length&&aisdk.trackPageView({}); | ||||
|   </script> | ||||
|   | ||||
							
								
								
									
										27
									
								
								server/modules/analytics/countly/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								server/modules/analytics/countly/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| head: | | ||||
|   <script type='text/javascript'> | ||||
|   //some default pre init | ||||
|   var Countly = Countly || {}; | ||||
|   Countly.q = Countly.q || []; | ||||
|  | ||||
|   //provide countly initialization parameters | ||||
|   Countly.app_key = '{{appKey}}'; | ||||
|   Countly.url = '{{serverUrl}}'; | ||||
|  | ||||
|   Countly.q.push(['track_sessions']); | ||||
|   Countly.q.push(['track_pageview']); | ||||
|   Countly.q.push(['track_clicks']); | ||||
|   Countly.q.push(['track_scrolls']); | ||||
|   Countly.q.push(['track_errors']); | ||||
|   Countly.q.push(['track_links']); | ||||
|  | ||||
|   //load countly script asynchronously | ||||
|   (function() { | ||||
|     var cly = document.createElement('script'); cly.type = 'text/javascript'; | ||||
|     cly.async = true; | ||||
|     //enter url of script here | ||||
|     cly.src = 'https://cdnjs.cloudflare.com/ajax/libs/countly-sdk-web/18.8.2/countly.min.js'; | ||||
|     cly.onload = function(){Countly.init()}; | ||||
|     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(cly, s); | ||||
|   })(); | ||||
|   </script> | ||||
| @@ -16,30 +16,3 @@ props: | ||||
|     title: Server URL | ||||
|     hint: The Count.ly server to report to. e.g. https://us-example.count.ly | ||||
|     order: 2 | ||||
| codeHead: | | ||||
|   <script type='text/javascript'> | ||||
|   //some default pre init | ||||
|   var Countly = Countly || {}; | ||||
|   Countly.q = Countly.q || []; | ||||
|  | ||||
|   //provide countly initialization parameters | ||||
|   Countly.app_key = '{{appKey}}'; | ||||
|   Countly.url = '{{serverUrl}}'; | ||||
|  | ||||
|   Countly.q.push(['track_sessions']); | ||||
|   Countly.q.push(['track_pageview']); | ||||
|   Countly.q.push(['track_clicks']); | ||||
|   Countly.q.push(['track_scrolls']); | ||||
|   Countly.q.push(['track_errors']); | ||||
|   Countly.q.push(['track_links']); | ||||
|  | ||||
|   //load countly script asynchronously | ||||
|   (function() { | ||||
|     var cly = document.createElement('script'); cly.type = 'text/javascript'; | ||||
|     cly.async = true; | ||||
|     //enter url of script here | ||||
|     cly.src = 'https://cdnjs.cloudflare.com/ajax/libs/countly-sdk-web/18.8.2/countly.min.js'; | ||||
|     cly.onload = function(){Countly.init()}; | ||||
|     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(cly, s); | ||||
|   })(); | ||||
|   </script> | ||||
|   | ||||
							
								
								
									
										10
									
								
								server/modules/analytics/elasticapm/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								server/modules/analytics/elasticapm/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| head: | | ||||
|   <!-- Elastic APM RUM --> | ||||
|   <script async src="https://unpkg.com/@elastic/apm-rum/dist/bundles/elastic-apm-rum.umd.min.js"></script> | ||||
|   <script> | ||||
|     elasticApm.init({ | ||||
|       serviceName: '{{serviceName}}', | ||||
|       serverUrl: '{{serverUrl}}', | ||||
|       environment: '{{environment}}' | ||||
|     }) | ||||
|   </script> | ||||
| @@ -24,13 +24,3 @@ props: | ||||
|     hint: e.g. production/development/test | ||||
|     default: '' | ||||
|     order: 3 | ||||
| codeHead: | | ||||
|   <!-- Elastic APM RUM --> | ||||
|   <script async src="https://unpkg.com/@elastic/apm-rum/dist/bundles/elastic-apm-rum.umd.min.js"></script> | ||||
|   <script> | ||||
|     elasticApm.init({ | ||||
|       serviceName: '{{serviceName}}', | ||||
|       serverUrl: '{{serverUrl}}', | ||||
|       environment: '{{environment}}' | ||||
|     }) | ||||
|   </script> | ||||
|   | ||||
							
								
								
									
										16
									
								
								server/modules/analytics/fathom/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								server/modules/analytics/fathom/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| head: | | ||||
|   <!-- Fathom - simple website analytics - https://github.com/usefathom/fathom --> | ||||
|   <script> | ||||
|   (function(f, a, t, h, o, m){ | ||||
|     a[h]=a[h]||function(){ | ||||
|       (a[h].q=a[h].q||[]).push(arguments) | ||||
|     }; | ||||
|     o=f.createElement('script'), | ||||
|     m=f.getElementsByTagName('script')[0]; | ||||
|     o.async=1; o.src=t; o.id='fathom-script'; | ||||
|     m.parentNode.insertBefore(o,m) | ||||
|   })(document, window, '{{host}}/tracker.js', 'fathom'); | ||||
|   fathom('set', 'siteId', '{{siteId}}'); | ||||
|   fathom('trackPageview'); | ||||
|   </script> | ||||
|   <!-- / Fathom --> | ||||
| @@ -16,19 +16,3 @@ props: | ||||
|     title: Site ID | ||||
|     hint: The alphanumeric identifier of your site | ||||
|     order: 2 | ||||
| codeHead: | | ||||
|   <!-- Fathom - simple website analytics - https://github.com/usefathom/fathom --> | ||||
|   <script> | ||||
|   (function(f, a, t, h, o, m){ | ||||
|     a[h]=a[h]||function(){ | ||||
|       (a[h].q=a[h].q||[]).push(arguments) | ||||
|     }; | ||||
|     o=f.createElement('script'), | ||||
|     m=f.getElementsByTagName('script')[0]; | ||||
|     o.async=1; o.src=t; o.id='fathom-script'; | ||||
|     m.parentNode.insertBefore(o,m) | ||||
|   })(document, window, '{{host}}/tracker.js', 'fathom'); | ||||
|   fathom('set', 'siteId', '{{siteId}}'); | ||||
|   fathom('trackPageview'); | ||||
|   </script> | ||||
|   <!-- / Fathom --> | ||||
|   | ||||
							
								
								
									
										18
									
								
								server/modules/analytics/fullstory/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								server/modules/analytics/fullstory/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| head: | | ||||
|   <script> | ||||
|   window['_fs_debug'] = false; | ||||
|   window['_fs_host'] = 'fullstory.com'; | ||||
|   window['_fs_org'] = '{{org}}'; | ||||
|   window['_fs_namespace'] = 'FS'; | ||||
|   (function(m,n,e,t,l,o,g,y){ | ||||
|       if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');} return;} | ||||
|       g=m[e]=function(a,b,s){g.q?g.q.push([a,b,s]):g._api(a,b,s);};g.q=[]; | ||||
|       o=n.createElement(t);o.async=1;o.crossOrigin='anonymous';o.src='https://'+_fs_host+'/s/fs.js'; | ||||
|       y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y); | ||||
|       g.identify=function(i,v,s){g(l,{uid:i},s);if(v)g(l,v,s)};g.setUserVars=function(v,s){g(l,v,s)};g.event=function(i,v,s){g('event',{n:i,p:v},s)}; | ||||
|       g.shutdown=function(){g("rec",!1)};g.restart=function(){g("rec",!0)}; | ||||
|       g.consent=function(a){g("consent",!arguments.length||a)}; | ||||
|       g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)}; | ||||
|       g.clearUserCookie=function(){}; | ||||
|   })(window,document,window['_fs_namespace'],'script','user'); | ||||
|   </script> | ||||
| @@ -11,21 +11,3 @@ props: | ||||
|     title: Organization ID | ||||
|     hint: A 5 alphanumeric identifier, e.g. XXXXX | ||||
|     order: 1 | ||||
| codeHead: | | ||||
|   <script> | ||||
|   window['_fs_debug'] = false; | ||||
|   window['_fs_host'] = 'fullstory.com'; | ||||
|   window['_fs_org'] = '{{org}}'; | ||||
|   window['_fs_namespace'] = 'FS'; | ||||
|   (function(m,n,e,t,l,o,g,y){ | ||||
|       if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');} return;} | ||||
|       g=m[e]=function(a,b,s){g.q?g.q.push([a,b,s]):g._api(a,b,s);};g.q=[]; | ||||
|       o=n.createElement(t);o.async=1;o.crossOrigin='anonymous';o.src='https://'+_fs_host+'/s/fs.js'; | ||||
|       y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y); | ||||
|       g.identify=function(i,v,s){g(l,{uid:i},s);if(v)g(l,v,s)};g.setUserVars=function(v,s){g(l,v,s)};g.event=function(i,v,s){g('event',{n:i,p:v},s)}; | ||||
|       g.shutdown=function(){g("rec",!1)};g.restart=function(){g("rec",!0)}; | ||||
|       g.consent=function(a){g("consent",!arguments.length||a)}; | ||||
|       g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)}; | ||||
|       g.clearUserCookie=function(){}; | ||||
|   })(window,document,window['_fs_namespace'],'script','user'); | ||||
|   </script> | ||||
|   | ||||
							
								
								
									
										10
									
								
								server/modules/analytics/google/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								server/modules/analytics/google/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| head: | | ||||
|   <!-- Global site tag (gtag.js) - Google Analytics --> | ||||
|   <script async src="https://www.googletagmanager.com/gtag/js?id={{propertyTrackingId}}"></script> | ||||
|   <script> | ||||
|     window.dataLayer = window.dataLayer || []; | ||||
|     function gtag(){dataLayer.push(arguments);} | ||||
|     gtag('js', new Date()); | ||||
|  | ||||
|     gtag('config', '{{propertyTrackingId}}'); | ||||
|   </script> | ||||
| @@ -1,6 +1,6 @@ | ||||
| key: google | ||||
| title: Google Analytics | ||||
| description: Google specializes in Internet-related services and products, which include online advertising technologies, search engine, cloud computing, software, and hardware. | ||||
| description: Google Analytics is a web analytics service offered by Google that tracks and reports website traffic. | ||||
| author: requarks.io | ||||
| logo: https://static.requarks.io/logo/google-analytics.svg | ||||
| website: https://analytics.google.com/ | ||||
| @@ -11,13 +11,3 @@ props: | ||||
|     title: Property Tracking ID | ||||
|     hint: UA-XXXXXXX-X | ||||
|     order: 1 | ||||
| codeHead: | | ||||
|   <!-- Global site tag (gtag.js) - Google Analytics --> | ||||
|   <script async src="https://www.googletagmanager.com/gtag/js?id={{propertyTrackingId}}"></script> | ||||
|   <script> | ||||
|     window.dataLayer = window.dataLayer || []; | ||||
|     function gtag(){dataLayer.push(arguments);} | ||||
|     gtag('js', new Date()); | ||||
|  | ||||
|     gtag('config', '{{propertyTrackingId}}'); | ||||
|   </script> | ||||
|   | ||||
							
								
								
									
										13
									
								
								server/modules/analytics/gtm/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								server/modules/analytics/gtm/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| head: | | ||||
|   <!-- Google Tag Manager --> | ||||
|   <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': | ||||
|   new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], | ||||
|   j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= | ||||
|   'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); | ||||
|   })(window,document,'script','dataLayer','{{containerTrackingId}}');</script> | ||||
|   <!-- End Google Tag Manager --> | ||||
| bodyStart: | | ||||
|   <!-- Google Tag Manager (noscript) --> | ||||
|   <noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{containerTrackingId}}" | ||||
|   height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> | ||||
|   <!-- End Google Tag Manager (noscript) --> | ||||
| @@ -1,6 +1,6 @@ | ||||
| key: gtm | ||||
| title: Google Tag Manager | ||||
| description: Google specializes in Internet-related services and products, which include online advertising technologies, search engine, cloud computing, software, and hardware. | ||||
| description: Google Tag Manager is a tag management system created by Google to manage JavaScript and HTML tags used for tracking and analytics on websites. | ||||
| author: requarks.io | ||||
| logo: https://static.requarks.io/logo/google-tag-manager.svg | ||||
| website: https://tagmanager.google.com | ||||
| @@ -11,16 +11,3 @@ props: | ||||
|     title: Container Tracking ID | ||||
|     hint: GTM-XXXXXXX | ||||
|     order: 1 | ||||
| codeHead: | | ||||
|   <!-- Google Tag Manager --> | ||||
|   <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': | ||||
|   new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], | ||||
|   j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= | ||||
|   'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); | ||||
|   })(window,document,'script','dataLayer','{{containerTrackingId}}');</script> | ||||
|   <!-- End Google Tag Manager --> | ||||
| codeBodyStart: | | ||||
|   <!-- Google Tag Manager (noscript) --> | ||||
|   <noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{containerTrackingId}}" | ||||
|   height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> | ||||
|   <!-- End Google Tag Manager (noscript) --> | ||||
|   | ||||
							
								
								
									
										12
									
								
								server/modules/analytics/hotjar/code.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								server/modules/analytics/hotjar/code.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| head: | | ||||
|   <!-- Hotjar Tracking Code --> | ||||
|   <script> | ||||
|     (function(h,o,t,j,a,r){ | ||||
|       h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; | ||||
|       h._hjSettings={hjid:{{siteId}},hjsv:6}; | ||||
|       a=o.getElementsByTagName('head')[0]; | ||||
|       r=o.createElement('script');r.async=1; | ||||
|       r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; | ||||
|       a.appendChild(r); | ||||
|     })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); | ||||
|   </script> | ||||
| @@ -11,15 +11,3 @@ props: | ||||
|     title: Site ID | ||||
|     hint: A numeric identifier of your site | ||||
|     order: 1 | ||||
| codeHead: | | ||||
|   <!-- Hotjar Tracking Code --> | ||||
|   <script> | ||||
|     (function(h,o,t,j,a,r){ | ||||
|       h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; | ||||
|       h._hjSettings={hjid:{{siteId}},hjsv:6}; | ||||
|       a=o.getElementsByTagName('head')[0]; | ||||
|       r=o.createElement('script');r.async=1; | ||||
|       r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; | ||||
|       a.appendChild(r); | ||||
|     })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); | ||||
|   </script> | ||||
|   | ||||
| @@ -51,7 +51,11 @@ html | ||||
|        | ||||
|      | ||||
|  | ||||
|     != analyticsCode.head | ||||
|  | ||||
|     block head | ||||
|  | ||||
|   body | ||||
|     != analyticsCode.bodyStart | ||||
|     block body | ||||
|     != analyticsCode.bodyEnd | ||||
|   | ||||
		Reference in New Issue
	
	Block a user