Skip to content

[AAASM-3557] 🐛 (docs): Make feedback widget always visible + fix version-banner JS#169

Closed
Chisanan232 wants to merge 3 commits into
masterfrom
v0.0.1/AAASM-3557/feedback_decouple
Closed

[AAASM-3557] 🐛 (docs): Make feedback widget always visible + fix version-banner JS#169
Chisanan232 wants to merge 3 commits into
masterfrom
v0.0.1/AAASM-3557/feedback_decouple

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

Description

The "Was this page helpful?" feedback widget (added in AAASM-3555, PR #168) is never visible to ordinary visitors on the published site, plus two secondary JS defects on every page. All three are fixed here, all in the mkdocs-material theme override (docs/_overrides) — no fork of the installed package, no new dependency.

(1) Feedback coupled to analytics consent (primary). mkdocs-material reveals form.md-feedback and wires the 👍/👎 handlers only inside its generated __md_analytics(), which runs only after analytics consent is granted. Our consent is opt-in (analytics.checked: false), so __md_analytics() never runs for normal visitors and the widget stays hidden forever. Fix: a document$-driven script in main.html that always reveals the widget and wires our own handlers (thank-you note + pre-filled GitHub issue link), but deliberately does not call gtag — Material's own handler still sends the GA feedback event only when consent is granted. This keeps the GA event consent-gated (GDPR posture preserved) and avoids double-counting.

(2) TypeError: Failed to construct 'URL': Invalid URL on every page. Material's partials/javascripts/outdated.html calls new URL("{{ base_url }}") with no base; base_url is a bare relative value (./..), so it throws on every load. Fixed by overriding that partial to pass location as the base.

(3) versions.json 404 on deep pages. The version-banner script in main.html built versionsUrl by popping only the page's last path segment, requesting /<base>/<version>/versions.json (404) on deep pages. Fixed to resolve from the rendered base_url (deploy root at any depth) → ../versions.json (deploy-root, 200).

Type of Change

  • 🔧 Bug fix

Breaking Changes

  • No

Related Issues

Testing

Local clean build (uv sync --group docs + uv run mkdocs build --strict) then served and driven with bundled chromium (playwright):

  • Manual testing performed
  • No unit tests required (theme-override JS in a docs-only theme; behaviour verified end-to-end in a real browser across root / mid / deep pages)

Browser verification results:

  • Widget visible without any consentform.hidden === false, 2 submit buttons present, on a normal page load.
  • Click 👍 (no consent) — thank-you note shows; 0 feedback events pushed to dataLayer.
  • Click 👎 (no consent) — note + pre-filled GitHub issue link show (correct href, target=_blank); still 0 events.
  • After granting analytics consent (scoped localStorage __consent = {"analytics":true}) + reload — click sends exactly 1 feedback event (no double-count; confirmed by counting dataLayer feedback pushes).
  • No Failed to construct 'URL' error in the console on root, mid, and deep pages (only expected versions.json 404 in the non-versioned local build, which is what fix (3) addresses for the real mike deploy).
  • mkdocs build --strict is clean.

GDPR posture preserved: the GA feedback event still fires only with analytics consent; our handler never calls gtag. No new dependency.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated if needed
  • All tests passing

🤖 Generated with Claude Code

Chisanan232 and others added 3 commits June 23, 2026 08:14
The 'Was this page helpful?' widget (AAASM-3555) was only revealed and
wired by mkdocs-material's __md_analytics(), which runs only after
analytics consent is granted. With opt-in consent (off by default) the
widget stayed hidden for all ordinary visitors.

Add a document$-driven script in the theme override that always reveals
the widget and wires the 👍/👎 handlers (thank-you note + issue link),
without calling gtag — Material's own handler still sends the GA feedback
event only when consent is granted, preserving the GDPR posture and
avoiding double-counting.

Refs AAASM-3557. Fixes AAASM-3555 regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Material's generated outdated-banner reveal script calls
new URL("{{ base_url }}") with no base argument; base_url is a bare
relative value like "." or "..", so new URL("..") throws
'TypeError: Failed to construct URL: Invalid URL' on every page load.

Override partials/javascripts/outdated.html to pass location as the base
(new URL(base_url, location)) instead of forking the installed material
package. Behaviour is otherwise identical.

Refs AAASM-3557.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The version-banner script built versionsUrl by popping only the page's
last path segment, so on deep pages it requested
/<base>/<version>/versions.json (404) instead of the deploy-root
/<base>/versions.json (200).

Resolve the URL from the rendered base_url (the deploy root, correct at
any page depth) and read ../versions.json relative to it, so the fetch
always hits the deploy-root versions.json.

Refs AAASM-3557.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Chisanan232

Copy link
Copy Markdown
Contributor Author

Claude Code — review result

CI green — both checks pass (documentation build, CodeQL); mkdocs build --strict clean. No fails to ignore. MERGEABLE.

Scope vs AAASM-3557 — all three parts covered, no package fork, no new dependency:

  1. Primary — feedback decoupled from analytics consent. A document$-driven script ({% block scripts %} + {{ super() }}) always sets form.feedback.hidden = false and wires our own 👍/👎 handlers (show note + disable), guarded by a per-form aaWired flag. It deliberately does not call gtag — mkdocs-material's own handler (active only with consent) remains the sole sender of the GA feedback event. This is the key correctness point: widget visible to everyone, event still consent-gated, no double-count. ✅
  2. new URL("..") TypeError — overrides docs/_overrides/partials/javascripts/outdated.html to pass the base: new URL("{{ base_url }}", location) — faithful to Material's script otherwise. ✅
  3. versions.json 404 — rewrites the version-banner URL builder to resolve from the rendered base_url (new URL("../versions.json", versionRoot)) so it hits the deploy-root versions.json from any page depth, not just version-root pages. ✅

Verified (bundled Chromium, served local strict build, deep page /configuration/):

  • Widget visible with no consent (form.hidden === false, both buttons present). ✅
  • 👍 / 👎 with no consent → note + pre-filled GitHub issue link show, 0 feedback events in dataLayer. ✅
  • With analytics consent (seeded via Material's scoped <scope>.__consent localStorage key, then reload) → click sends exactly 1 event (no double-count). ✅
  • No Failed to construct 'URL' errors across root/mid/deep pages. ✅

Sound side-effect: this also makes python's GA (AAASM-3552) actually reachable, since the same opt-in cookie previously gated everything. GDPR posture preserved.

Ready for approval + merge. (Post-merge: re-verify on the live versioned /python-sdk/latest/ — the versions.json/outdated paths only fully exercise under mike, which a plain local build can't reproduce.)

@Chisanan232

Copy link
Copy Markdown
Contributor Author

Closing unmerged — superseded by AAASM-3558.

Per owner decision (Claude Code review): the python feedback widget's visibility issue is part of a deeper problem — on the live site GA never loads at all for a normal visitor (window.gtag undefined, zero /g/collect hits), because mkdocs-material uses basic Consent Mode (loads gtag only after the opt-in analytics cookie, which is off by default). The other four doc sites use advanced Consent Mode v2 (gtag always loads, cookieless pings when denied).

Rather than land this widget-only decouple, python's analytics is being reworked comprehensively under AAASM-3558 to match the other four sites (self-managed gtag + Consent Mode v2). That rework folds in everything this PR did and more:

  • always-visible feedback widget + consent-gated event (no double-count),
  • the new URL("..", location) outdated-banner fix,
  • the versions.json deep-page path fix,
  • plus making GA actually fire + be detectable.

Closing this PR; the carried-over fixes will land via AAASM-3558. Thanks for the work here — it directly informed the rework.

@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-3557/feedback_decouple branch June 23, 2026 01:45
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.

1 participant