Skip to content

Commit 9bec906

Browse files
authored
Merge pull request #5404 from HSLdevcom/DT-6880-v3
DT-6880 server side analytics injection into v3
2 parents d6cd2f1 + 7a37d5d commit 9bec906

File tree

3 files changed

+52
-29
lines changed

3 files changed

+52
-29
lines changed

app/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ export default async function serve(req, res, next) {
328328

329329
// Write preload hints before doing anything else
330330
if (process.env.NODE_ENV !== 'development') {
331-
res.write(getAnalyticsInitCode(config, req.hostname));
331+
res.write(getAnalyticsInitCode(config, req));
332332

333333
const preloads = [
334334
{ as: 'style', href: config.URL.FONT },

app/util/analyticsUtils.js

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Cookies from 'universal-cookie';
2+
13
/**
24
* This file contains functions for UI analytics.
35
* Contains code used in both client and server
@@ -12,18 +14,12 @@
1214
* @return void
1315
*/
1416
export function addAnalyticsEvent(event) {
15-
let newEvent = event;
16-
const config = window.state?.context?.plugins['extra-context-plugin'].config;
17-
if (event.event === undefined) {
18-
// this is the default event field if none is defined
19-
newEvent = { event: 'sendMatomoEvent', ...event };
20-
}
21-
22-
if (
23-
(config?.useCookiesPrompt &&
24-
window.CookieInformation?.getConsentGivenFor('cookie_cat_statistic')) ||
25-
!config?.useCookiesPrompt
26-
) {
17+
if (window.dataLayer) {
18+
let newEvent = event;
19+
if (event.event === undefined) {
20+
// this is the default event field if none is defined
21+
newEvent = { event: 'sendMatomoEvent', ...event };
22+
}
2723
window.dataLayer.push(newEvent);
2824
}
2925
}
@@ -35,7 +31,15 @@ export function addAnalyticsEvent(event) {
3531
*
3632
* @return string
3733
*/
38-
export function getAnalyticsInitCode(config, hostname) {
34+
export function getAnalyticsInitCode(config, req) {
35+
const { hostname, cookies } = req;
36+
const useAnalytics =
37+
!config.useCookiesPrompt || cookies.cookieConsent === 'true';
38+
39+
if (!useAnalytics) {
40+
return '';
41+
}
42+
3943
if (
4044
config.analyticsScript &&
4145
hostname &&
@@ -47,30 +51,51 @@ export function getAnalyticsInitCode(config, hostname) {
4751
);
4852
}
4953

50-
if (config.GTMid) {
51-
// Google Tag Manager script
52-
return `<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
54+
let script = config.GTMid
55+
? // Google Tag Manager script
56+
`<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
5357
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
5458
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
5559
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
56-
})(window,document,'script','dataLayer','${config.GTMid}');</script>\n`;
60+
})(window,document,'script','dataLayer','${config.GTMid}');</script>\n`
61+
: '';
62+
if (config.crazyEgg) {
63+
script = `${script}<script type="text/javascript" src="//script.crazyegg.com/pages/scripts/0030/3436.js" async="async" ></script>`;
5764
}
58-
return '';
65+
return script;
5966
}
67+
6068
const handleChange = () => {
6169
if (!window.CookieInformation) {
6270
return false;
6371
}
64-
return window.CookieInformation.getConsentGivenFor('cookie_cat_statistics');
72+
const allow = window.CookieInformation.getConsentGivenFor(
73+
'cookie_cat_statistic',
74+
);
75+
const cookies = new Cookies();
76+
const oldState = cookies.get('cookieConsent') === true;
77+
cookies.set('cookieConsent', allow);
78+
if (oldState && !allow) {
79+
// no consent any more, reload page
80+
window.location.reload();
81+
}
82+
return allow;
6583
};
84+
6685
/**
6786
* Client side intialization for UI analytics
6887
*
6988
* @return void
7089
*/
7190
export function initAnalyticsClientSide(config) {
72-
window.dataLayer = window.dataLayer || [];
73-
if (config?.useCookiesPrompt) {
91+
const cookies = new Cookies();
92+
const useAnalytics =
93+
!config.useCookiesPrompt || cookies.get('cookieConsent') === true;
94+
95+
if (useAnalytics) {
96+
window.dataLayer = window.dataLayer || [];
97+
}
98+
if (config.useCookiesPrompt) {
7499
window.addEventListener(
75100
'CookieInformationConsentGiven',
76101
handleChange,

test/unit/util/analyticsUtils.test.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
initAnalyticsClientSide,
55
} from '../../../app/util/analyticsUtils';
66

7+
const req = { hostname: 'foo', cookies: {} };
78
describe('analytics utils', () => {
89
describe('addAnalyticsEvent', () => {
910
it('should add a new entry to window.dataLayer', () => {
@@ -29,28 +30,25 @@ describe('analytics utils', () => {
2930
});
3031
describe('getAnalyticsInitCode', () => {
3132
it('should return a nonempty string when GTMid is given', () => {
32-
const res = getAnalyticsInitCode({ GTMid: 1 });
33+
const res = getAnalyticsInitCode({ GTMid: 1 }, req);
3334
expect(res.length > 0).to.equal(true);
3435
});
3536
it('should return an empty string when null GTMid and no analyticsScript is given', () => {
3637
const res = getAnalyticsInitCode(
3738
{ GTMid: null, analyticsScript: '' },
38-
'hostname',
39+
req,
3940
);
4041
expect(res.length).to.equal(0);
4142
});
4243
it('should return a nonempty string when analyticsScript and hostname are given', () => {
43-
const res = getAnalyticsInitCode(
44-
{ analyticsScript: () => 'test' },
45-
'hostname',
46-
);
44+
const res = getAnalyticsInitCode({ analyticsScript: () => 'test' }, req);
4745
expect(res.length > 0).to.equal(true);
4846
});
4947
});
5048
describe('initAnalyticsClientSide', () => {
5149
it('should initialize window.dataLayer to an array', () => {
5250
window.dataLayer = undefined;
53-
initAnalyticsClientSide();
51+
initAnalyticsClientSide({});
5452
expect(Array.isArray(window.dataLayer)).to.equal(true);
5553
});
5654
});

0 commit comments

Comments
 (0)