Reimplement Plausible analytics - #704
Conversation
The tracker was inlined into main.html with a bare init, which meant the `privacy` plugin downloaded it at build time and served a frozen self-hosted copy, and every referrer reached Plausible untouched. Visitors arriving from their own Home Assistant or ESPHome instance send that private URL as the referrer, so those had to be filtered before Plausible ever recorded them. - Move the tracker into a `partials/plausible.html` partial, included from the `extrahead` block, and read the script and dashboard URLs from `extra` in mkdocs.yml. - Exclude the Plausible host from the `privacy` plugin so the tracker is loaded from the Plausible instance and stays current. - Add a `source/hooks/plausible.py` hook that fetches the Open Home Foundation referrer allow list once per build, caches it under `.cache` alongside the translations, and exposes it to the templates. Fetch failures fall back to the cached copy and never fail the build. - Initialize the tracker with a `transformRequest` that replaces any referrer outside the allow list with a single `unlisted.invalid` bucket, so we can see how much is filtered without learning anything about individual visitors. - Guard the 404 event on `window.plausible` and point the footer dashboard link at the configured URL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UkMvZDbHQRYGY1u1P53uFd
There was a problem hiding this comment.
Pull request overview
This PR reimplements Plausible analytics integration for the MkDocs site to prevent private referrer URLs (e.g., from Home Assistant / ESPHome) from being recorded by Plausible, by fetching an allow list at build time and filtering referrers client-side before events are sent.
Changes:
- Moved Plausible initialization into a dedicated
partials/plausible.htmlpartial and included it frommain.html. - Added an MkDocs hook to fetch/cache an Open Home Foundation referrer allow list and expose it via
config.extrafor templating. - Updated MkDocs config to keep Plausible assets remote (privacy plugin exclude) and parameterized tracker/dashboard URLs via
extra.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| source/overrides/partials/plausible.html | Adds Plausible init with transformRequest referrer filtering using a build-fetched allow list. |
| source/overrides/partials/footer.html | Points the public dashboard link at a configurable config.extra.plausible.dashboard URL. |
| source/overrides/main.html | Includes the new Plausible partial from the extrahead block. |
| source/overrides/404.html | Guards the 404 Plausible event call on window.plausible availability. |
| source/hooks/plausible.py | Adds build-time allow list fetch + cache logic and injects it into config.extra.plausible.allowed_referrers. |
| source/assets/stylesheets/extra.css | Removes an extraneous blank line (no functional change). |
| mkdocs.yml | Configures privacy plugin asset exclusions, registers the new hook, and adds Plausible script/dashboard URLs under extra. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Merging main into this branch silently dropped the script src bump from hacs#702, because that commit edited the tracker line in main.html while this branch had replaced that whole file with an include. Move the new ID into the `extra` value the partial reads. Also declare `requests` explicitly. source/macros.py has always imported it and both pinned plugins depend on it, so builds were never actually broken, but the hook makes a second first-party use of a package the project never asked for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UkMvZDbHQRYGY1u1P53uFd
| @@ -1,2 +1,3 @@ | |||
| mkdocs-material[imaging]==9.7.5 | |||
| mkdocs-macros-plugin==1.5.0 | |||
| requests==2.33.1 | |||
| <h1>404 - Not found</h1> | ||
| <script> | ||
| document.addEventListener("DOMContentLoaded", function () { | ||
| if (typeof window.plausible === "function") window.plausible("404"); |
There was a problem hiding this comment.
| if (typeof window.plausible === "function") window.plausible("404"); | |
| if (typeof window.plausible === "function") { | |
| window.plausible("404") | |
| }; |
| {#- | ||
| Plausible analytics. | ||
|
|
||
| Visitors arriving from their own Home Assistant or ESPHome instance send that |
| for (var index = 0; index < allowedReferrers.length; index++) { | ||
| var domain = allowedReferrers[index]; | ||
| if (host === domain || (host.length > domain.length && host.slice(-(domain.length + 1)) === "." + domain)) { | ||
| return payload; | ||
| } | ||
| } |
There was a problem hiding this comment.
There is no need to do this loop if the try/catch above failed as host will be ""
| try { | ||
| host = new URL(payload.r).hostname.replace(/\.$/, ""); | ||
| } catch (error) { | ||
| // A referrer we cannot parse falls through and gets replaced. |
There was a problem hiding this comment.
Should probably return early here then.
| return cached | ||
| log.info( | ||
| f"Could not fetch the allow list ({exception}), " | ||
| "every referrer will be reported to Plausible as unlisted" |
There was a problem hiding this comment.
Does this have any value, should this not:
a) Fail the build
b) Disable Plausible
|
|
||
| var host = ""; | ||
| try { | ||
| host = new URL(payload.r).hostname.replace(/\.$/, ""); |
| except FileNotFoundError: | ||
| return None | ||
| except (OSError, ValueError) as exception: | ||
| log.info(f"Discarding unusable allow list at {ALLOWLIST_FILE}: {exception}") |
There was a problem hiding this comment.
| log.info(f"Discarding unusable allow list at {ALLOWLIST_FILE}: {exception}") | |
| log.info("Discarding unusable allow list at %s: %s", ALLOWLIST_FILE, exception) |
The same goes for your other loggers as well
The tracker was inlined into main.html with a bare init, which meant the
privacyplugin downloaded it at build time and served a frozen self-hosted copy, and every referrer reached Plausible untouched. Visitors arriving from their own Home Assistant or ESPHome instance send that private URL as the referrer, so those had to be filtered before Plausible ever recorded them.partials/plausible.htmlpartial, included from theextraheadblock, and read the script and dashboard URLs fromextrain mkdocs.yml.privacyplugin so the tracker is loaded from the Plausible instance and stays current.source/hooks/plausible.pyhook that fetches the Open Home Foundation referrer allow list once per build, caches it under.cachealongside the translations, and exposes it to the templates. Fetch failures fall back to the cached copy and never fail the build.transformRequestthat replaces any referrer outside the allow list with a singleunlisted.invalidbucket, so we can see how much is filtered without learning anything about individual visitors.window.plausibleand point the footer dashboard link at the configured URL.Claude-Session: https://claude.ai/code/session_01UkMvZDbHQRYGY1u1P53uFd