Skip to content

Commit 69763d1

Browse files
authored
feat: analytics support for form-level tracking (#378)
- Update server to dynamically inject analytics on a per-form basis, replacing the previous global-only setting. - Enables each form to have its own tracking analytics configuration. - Note: This ignores the global server-wide config! Existing forms should be updated to include analytics in their form definitions. Format example: analytics: { gtmId1: string; gtmId2: string; matomoId: string; matomoUrl: string; } This object is *optional*. All items in this object are also *optional*.
1 parent d242c8c commit 69763d1

4 files changed

Lines changed: 50 additions & 23 deletions

File tree

model/src/data-model/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ export type ExitOptions = {
188188
format?: "STATE" | "WEBHOOK";
189189
};
190190

191+
export type Analytics = {
192+
gtmId1: string;
193+
gtmId2: string;
194+
matomoId: string;
195+
matomoUrl: string;
196+
};
197+
191198
/**
192199
* `FormDefinition` is a typescript representation of `Schema`
193200
*/
@@ -214,6 +221,7 @@ export type FormDefinition = {
214221
jwtKey?: string | undefined;
215222
toggle?: boolean | string | undefined;
216223
retryTimeoutSeconds?: number | undefined;
224+
analytics?: Analytics;
217225
webhookHmacSharedKey?: string | undefined;
218226
fullStartPage?: string | undefined;
219227
serviceName?: string | undefined;

model/src/schema/schema.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ const feeSchema = joi.object().keys({
209209
prefix: joi.string().optional(),
210210
});
211211

212+
const analyticsSchema = joi.object().keys({
213+
gtmId1: joi.string().allow("").optional(),
214+
gtmId2: joi.string().allow("").optional(),
215+
matomoId: joi.string().allow("").optional(),
216+
matomoUrl: joi.string().uri().allow("").optional(),
217+
});
218+
212219
const multiApiKeySchema = joi.object({
213220
test: joi.string().optional(),
214221
smoke: joi.string().optional(),
@@ -346,6 +353,7 @@ export const Schema = joi
346353
toggle: joi.alternatives().try(joi.boolean(), joi.string()).optional(),
347354
toggleRedirect: joi.string().optional(),
348355
retryTimeoutSeconds: joi.number().optional(),
356+
analytics: analyticsSchema.optional(),
349357
webhookHmacSharedKey: joi.string().optional(),
350358
fullStartPage: joi.string().optional(),
351359
serviceName: joi.string().optional(),

runner/src/server/forms/ReportAnOutbreak.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
"metadata": {},
33
"authentication": true,
44
"toggle": "${magicLinkToggle}",
5+
"analytics": {
6+
"gtmId1": "GTM-MM6VPCXX"
7+
},
58
"startPage": "/start",
69
"pages": [
710
{

runner/src/server/plugins/views.ts

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,36 @@ export default {
6161
`${path.dirname(resolve.sync("hmpo-components"))}/components`,
6262
],
6363
isCached: !config.isDev,
64-
context: (request: HapiRequest) => ({
65-
appVersion: pkg.version,
66-
assetPath: "/assets",
67-
cookiesPolicy: request?.state?.cookies_policy,
68-
serviceName: capitalize(request.server?.app?.forms?.[request.params?.id]?.def?.serviceName || config.serviceName),
69-
feedbackLink: config.feedbackLink,
70-
pageTitle: (request.server?.app?.forms?.[request.params?.id]?.def?.serviceName || config.serviceName) + " - GOV.UK",
71-
analyticsAccount: config.analyticsAccount,
72-
gtmId1: config.gtmId1,
73-
gtmId2: config.gtmId2,
74-
location: request?.app.location,
75-
matomoId: config.matomoId,
76-
matomoUrl: config.matomoUrl,
77-
BROWSER_REFRESH_URL: config.browserRefreshUrl,
78-
sessionTimeout: config.sessionTimeout,
79-
skipTimeoutWarning: false,
80-
serviceStartPage: request.server?.app?.forms?.[request.params?.id]?.def?.fullStartPage || config.serviceName || "#",
81-
privacyPolicyUrl: config.privacyPolicyUrl || "/help/privacy",
82-
phaseTag: config.phaseTag,
83-
navigation: request?.auth.isAuthenticated
84-
? [{ text: "Sign out", href: "/logout" }]
85-
: null,
86-
}),
64+
context: (request: HapiRequest) => {
65+
const id = request.params?.id;
66+
const forms = request.server?.app?.forms;
67+
const model = id && forms?.[id];
68+
const analytics = model?.def?.analytics || {};
69+
70+
return {
71+
appVersion: pkg.version,
72+
assetPath: "/assets",
73+
cookiesPolicy: request?.state?.cookies_policy,
74+
serviceName: capitalize(request.server?.app?.forms?.[request.params?.id]?.def?.serviceName || config.serviceName),
75+
feedbackLink: config.feedbackLink,
76+
pageTitle: (request.server?.app?.forms?.[request.params?.id]?.def?.serviceName || config.serviceName) + " - GOV.UK",
77+
analyticsAccount: config.analyticsAccount,
78+
gtmId1: analytics.gtmId1 || "",
79+
gtmId2: analytics.gtmId2 || "",
80+
location: request?.app.location,
81+
matomoId: analytics.matomoId || "",
82+
matomoUrl: analytics.matomoUrl || "",
83+
BROWSER_REFRESH_URL: config.browserRefreshUrl,
84+
sessionTimeout: config.sessionTimeout,
85+
skipTimeoutWarning: false,
86+
serviceStartPage: request.server?.app?.forms?.[request.params?.id]?.def?.fullStartPage || config.serviceName || "#",
87+
privacyPolicyUrl: config.privacyPolicyUrl || "/help/privacy",
88+
phaseTag: config.phaseTag,
89+
navigation: request?.auth.isAuthenticated
90+
? [{ text: "Sign out", href: "/logout" }]
91+
: null,
92+
};
93+
},
94+
8795
},
8896
};

0 commit comments

Comments
 (0)