diff --git a/.github/workflows/site.yml b/.github/workflows/site.yml
index a829196..75eed1f 100644
--- a/.github/workflows/site.yml
+++ b/.github/workflows/site.yml
@@ -63,6 +63,9 @@ jobs:
- name: Build
id: build
run: npm run build
+ env:
+ # Public by design: the token ends up in every page. Leave the variable unset to build without analytics.
+ PUBLIC_CLOUDFLARE_ANALYTICS_TOKEN: ${{ vars.CLOUDFLARE_ANALYTICS_TOKEN }}
- name: Upload Site
id: upload
diff --git a/README.md b/README.md
index 792caf2..0957c66 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,8 @@ CI checks out the newest brand release into `.brand` on every build, and builds
Every push to `main`, and every morning, builds the site and publishes it to GitHub Pages. Pull requests build it without publishing, so you can break things in private.
+The published site counts visits with [Cloudflare Web Analytics](https://www.cloudflare.com/web-analytics/). It sets no cookies and keeps no personal data, so there's no banner to click through. The build only adds it when the `CLOUDFLARE_ANALYTICS_TOKEN` repository variable is set, so forks and local builds count nobody.
+
## Contributing and support
Spotted a typo, a broken link or a template we forgot? Open an issue or a pull request. Branch from `main` as `feature/`, `fix/` or `chore/`, run `npm run build` before you push, and keep each change to one thing. The organisation's [contributing guide](https://github.com/LeanMeanCleanApps/.github/blob/main/CONTRIBUTING.md), [code of conduct](https://github.com/LeanMeanCleanApps/.github/blob/main/CODE_OF_CONDUCT.md) and [security policy](https://github.com/LeanMeanCleanApps/.github/blob/main/SECURITY.md) apply here too.
diff --git a/src/components/Analytics.astro b/src/components/Analytics.astro
new file mode 100644
index 0000000..ee6921f
--- /dev/null
+++ b/src/components/Analytics.astro
@@ -0,0 +1,17 @@
+---
+// Cloudflare Web Analytics. It sets no cookies and keeps no personal data, so there's no banner to accept.
+// The token comes from the CLOUDFLARE_ANALYTICS_TOKEN repository variable at build time. Without it, as in a fork or
+// on your machine, nothing is added and nobody is counted.
+const token = import.meta.env.PUBLIC_CLOUDFLARE_ANALYTICS_TOKEN;
+---
+
+{
+ token && (
+
+ )
+}
diff --git a/src/components/docs/Head.astro b/src/components/docs/Head.astro
index f783a32..df79a09 100644
--- a/src/components/docs/Head.astro
+++ b/src/components/docs/Head.astro
@@ -2,6 +2,7 @@
// Gives each template's pages, and the brand pages, their own accent colour and link preview, picked from the first
// part of the page's path.
import Default from '@astrojs/starlight/components/Head.astro';
+import Analytics from '../Analytics.astro';
import { brand, templates } from '../../data/templates';
const accents = import.meta.glob('../../styles/docs/accents/*.css', { query: '?raw', import: 'default', eager: true });
@@ -22,3 +23,4 @@ const [width, height] = template || isBrand ? [1280, 640] : [1200, 630];
+
diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro
index 5547944..3d7a8f7 100644
--- a/src/layouts/Base.astro
+++ b/src/layouts/Base.astro
@@ -1,4 +1,5 @@
---
+import Analytics from '../components/Analytics.astro';
import '../styles/layers.css';
import '@fontsource-variable/bricolage-grotesque';
import '@fontsource-variable/inter';
@@ -52,6 +53,7 @@ const community = `${github}/.github/blob/main`;
+
Skip to content