Skip to content

Stream web analytics data to Umami - #187

Merged
sjlegg merged 1 commit into
mainfrom
umami
Oct 19, 2026
Merged

sjlegg merged 1 commit into
mainfrom
umami

Conversation

@sjlegg

@sjlegg sjlegg commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor
  • JS snippet in <head> to stream web analytics data to Umami (NHSE-hosted in AWS)
  • New privacy notice
  • Add link to privacy notice to footer
  • Apply Content Security Policy (CSP) to all pages via a <meta> tag in the <head> - tested by running locally and checking logs for CSP violations, as well as LLM pixel-by-pixel comparison of screenshots before/after to check for missing fonts, style sheets etc.

See also: DPIA screening questionnaire, approved by IG team & signed off by Rachel Hope as Information Asset Owner for the new information asset this will create.

@sjlegg
sjlegg requested review from csutter and a balanced review from Copilot August 18, 2026 16:04
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 18, 2026 16:04 Inactive

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Umami web analytics and documents the associated privacy handling.

Changes:

  • Injects the Umami analytics script site-wide.
  • Adds and links a new privacy policy.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
eleventy.config.mjs Adds footer link and analytics transform.
app/privacy-policy.md Documents analytics data processing.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/privacy-policy.md Outdated
Comment thread eleventy.config.mjs Outdated

This comment was marked as outdated.

@sjlegg sjlegg linked an issue Aug 19, 2026 that may be closed by this pull request
@annapowellsmith-nhs
annapowellsmith-nhs marked this pull request as draft August 19, 2026 14:00
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 15:10 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 15:50 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 15:51 Inactive
@sjlegg
sjlegg requested a balanced review from Copilot August 19, 2026 15:52

This comment was marked as resolved.

This comment was marked as resolved.

@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 16:23 Inactive
@sjlegg
sjlegg requested a balanced review from Copilot August 19, 2026 16:24

This comment was marked as resolved.

@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 16:33 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 16:40 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 19, 2026 16:42 Inactive
@annapowellsmith-nhs

Copy link
Copy Markdown

Lovely 🙌 I've deleted previous comments that are now outdated following our offline discussion.

Two minor things:

  • I wonder if we want to serve the script from a prettier URL like analytics.digital-prevention-services.nhs.uk, and lose crossorigin="anonymous" - one for @csutter to decide, I think.
  • Presumably the DPSP site admins will need to set up a CSP for this. Worth flagging that in this PR I think.

@NHSDigital NHSDigital deleted a comment from sjlegg Aug 24, 2026
@csutter

csutter commented Aug 24, 2026

Copy link
Copy Markdown

Looks good in principle!

It's not clear from the Umami docs whether different versions of the tracking script work with different versions of Umami, or if there's a risk of issues if they diverge. Either way it's probably worth us versioning the script files on the bucket like v3.3.1/script.js as part of deploying a new Umami version (in addition to the sensible use of a SHA).

I wonder if we want to serve the script from a prettier URL like analytics.digital-prevention-services.nhs.uk

We can set up an appropriate nhs.uk subdomain when the time comes (I believe www.digital-prevention-services.nhs.uk is just a CNAME and we haven't delegated a zone to us so we'll have to make a request to the DNS team).

Presumably the DPSP site admins will need to set up a CSP for this.

Can we do that in this PR? This will need a <meta> tag as we can't add custom headers on GitHub pages.

@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 25, 2026 13:57 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 August 25, 2026 15:48 Inactive
@sjlegg

sjlegg commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Looks good in principle!

It's not clear from the Umami docs whether different versions of the tracking script work with different versions of Umami, or if there's a risk of issues if they diverge. Either way it's probably worth us versioning the script files on the bucket like v3.3.1/script.js as part of deploying a new Umami version (in addition to the sensible use of a SHA).

I wonder if we want to serve the script from a prettier URL like analytics.digital-prevention-services.nhs.uk

We can set up an appropriate nhs.uk subdomain when the time comes (I believe www.digital-prevention-services.nhs.uk is just a CNAME and we haven't delegated a zone to us so we'll have to make a request to the DNS team).

Presumably the DPSP site admins will need to set up a CSP for this.

Can we do that in this PR? This will need a <meta> tag as we can't add custom headers on GitHub pages.

Thanks @csutter. I have added a CSP to this PR and tested it. I'll work on the version tracking in parallel. We're still waiting on an outcome of the DPIA screen for this.

Please can you provide details off this PR of how to make the request to the DNS team for the subdomain, or should this wait for the outcome of the DPIA screen first?

@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 September 3, 2026 13:47 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 September 3, 2026 13:48 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 September 30, 2026 11:23 Inactive
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 September 30, 2026 11:26 Inactive
@sjlegg
sjlegg marked this pull request as ready for review October 19, 2026 10:24
@sjlegg sjlegg changed the title [DO NOT MERGE] Stream web analytics data to Umami Stream web analytics data to Umami Oct 19, 2026

@stevenjmesser stevenjmesser left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Generally these external-facing docs are referred to as privacy notices these days, whereas the privacy policy is more of an internal thing. Also, this references a privacy notice on the NHS England website, so these changes make this doc consistent with those others.

Comment thread app/privacy-policy.md Outdated
Comment thread app/privacy-policy.md Outdated
Comment thread app/privacy-policy.md Outdated
Comment thread eleventy.config.mjs Outdated
Comment thread eleventy.config.mjs Outdated
Comment thread app/privacy-notice.md
- Add JS snippet in <head> to stream web analytics data to Umami (NHSE-hosted in AWS)
- Add new privacy notice page
- Add link to privacy notice to footer
- Add Content Security Policy (CSP) via a <meta> tag in the <head> of all pages; tested by running locally and checking logs for CSP violations, and by comparing before/after screenshots to check for missing fonts, style sheets etc.

See also: DPIA screening questionnaire, approved by IG team and signed off by Rachel Hope as Information Asset Owner for the new information asset this will create.
@frankieroberto
frankieroberto temporarily deployed to dpsp-website-umami-dvheupcg8z0 October 19, 2026 11:00 Inactive
@sjlegg
sjlegg requested a review from stevenjmesser October 19, 2026 11:01

@stevenjmesser stevenjmesser left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this!

@sjlegg
sjlegg merged commit 4b67398 into main Oct 19, 2026
3 checks passed
@sjlegg
sjlegg deleted the umami branch October 19, 2026 11:15
frankieroberto pushed a commit to NHSDigital/prevention-services-design-history that referenced this pull request Oct 20, 2026
## Summary

Streams web analytics for the design history site to the NHSE-hosted
Umami instance, so we can understand how the site is used. This
replicates the approach in
[digital-prevention-services-portfolio#187](NHSDigital/digital-prevention-services-portfolio#187):
the tracker, a Content Security Policy (CSP) and a privacy notice are
added together because the CSP is needed to constrain what the tracker
can load, and the notice is needed to explain what is collected.

The site is hosted on GitHub Pages, where custom headers cannot be set,
so the CSP is applied with a `<meta>` tag.

## Changes

**Analytics tracker** ([eleventy.config.js](eleventy.config.js))
- Inject the Umami script into every page using the existing analytics
host (`analytics.digital-prevention-services.nhs.uk`) and a new website
ID for this site, restricted to
`design-history.prevention-services.nhs.uk`.
- Place the script after `application.js` so it cannot delay the page's
own scripts (deferred scripts run in document order).

**Content Security Policy** ([eleventy.config.js](eleventy.config.js))
- Inject a CSP `<meta>` tag at the top of every page's `<head>`.
- Allow the Umami host for scripts and connections, plus `assets.nhs.uk`
for NHS fonts.
- Allow the Vimeo player (script and frame) used on one post, and
`user-images.githubusercontent.com` for the embedded videos on six older
posts.
- Allow inline styles, which the Vimeo embed relies on, and a hash for
the one inline script in the NHS layout.

**Privacy notice** ([app/privacy-notice.md](app/privacy-notice.md))
- Add a notice covering what analytics data is collected, retention,
lawful basis, individual rights and contact details, tailored to this
site.
- Link it from the footer.

**Redirect pages** ([app/redirects.njk](app/redirects.njk))
- Add a `<head>` so the CSP and tracker transform applies to redirect
pages.
- Remove the inline `location = ...` script, which the CSP would block;
the existing meta refresh performs the redirect.

## Validation

- `npm run build` succeeds; all 595 generated HTML pages contain the CSP
and the Umami script, with the script after `application.js`.
- Compared a build of `main` against this branch for a random 5% of
pages (plus all pages with videos), at 1280px and 390px, using
screenshots above the footer: pixel-identical apart from the new footer
link, and no CSP violations in the browser console. This caught the
GitHub video host missing from the first version of the CSP.
- ESLint and Prettier pass for the changed JavaScript. The build still
reports the existing NHS Sass deprecation warning.

## Notes for reviewers

- The Vimeo embed's rendering was not covered by the screenshot
comparison, so it is worth checking on
`vaccinations/2026/09/how-rosie-got-vaccinated`.

This branch was previously deployed

1 inactive deployment
dpsp-website-umami-dvheupcg8z0 — 1e577d17 Deployed Oct 19, 2026 by frankieroberto
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add privacy-friendly analytics

6 participants