Skip to content

feat(glean): port missing measurements#1279

Open
caugner wants to merge 41 commits intomainfrom
add-missing-measurements
Open

feat(glean): port missing measurements#1279
caugner wants to merge 41 commits intomainfrom
add-missing-measurements

Conversation

@caugner
Copy link
Copy Markdown
Contributor

@caugner caugner commented Feb 4, 2026

Description

Adds several missing Glean measurements, and corrects some.

Motivation

Ensure we can make data-driven decisions about the affected features.

Additional details

Related issues and pull requests

Related to #647.

Fixes several issues, mentioned directly in the commits.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 4, 2026

ef1d48e was deployed to: https://fred-pr1279.review.mdn.allizom.net/

Comment thread components/a11y-menu/server.js Outdated
Comment thread components/a11y-menu/server.js Outdated
Comment thread components/color-theme/element.js Outdated
Comment thread components/color-theme/element.js Outdated
Comment thread components/language-switcher/element.js Outdated
Comment thread hooks/glean-init.js Outdated
Comment thread components/menu/server.js Outdated
Comment thread hooks/glean-init.js Outdated
Comment thread components/playground/element.js
Comment thread components/collection-save-button/element.js Outdated
Comment thread components/playground/element.js Outdated
@caugner caugner changed the title feat(glean): add missing measurements feat(glean): port missing measurements Feb 4, 2026
@caugner caugner force-pushed the add-missing-measurements branch from 7f33adc to e453d13 Compare February 4, 2026 12:30
Instead, measure the top nav login in the `user-menu` component,
which does NOT use the `login-button` component.
Copy link
Copy Markdown
Contributor Author

@caugner caugner left a comment

Choose a reason for hiding this comment

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

Reviewed all changes, will test next.

@caugner
Copy link
Copy Markdown
Contributor Author

caugner commented Feb 11, 2026

Glean Measurement Testing Checklist

Setup: Enable Glean by setting FRED_GLEAN_ENABLED=true in .env and monitor gleanClick() calls in the browser console (e.g. breakpoint in hooks/glean-init.js).

Accessibility Menu (a11y-menu)

  • Tab into the a11y menu and click "Skip to main content" — fires a11y_menu: click #content
  • Tab into the a11y menu and click "Skip to search" — fires a11y_menu: click #search

Theme Switcher (color-theme)

  • Open the theme dropdown — fires theme_switcher: open
  • Close the theme dropdown without changing — fires theme_switcher: close
  • Switch to dark theme — fires theme_switcher: switch -> dark
  • Switch to light theme — fires theme_switcher: switch -> light
  • Switch to OS default — fires theme_switcher: switch -> os-default

Menu Bar (menu)

  • Click each top-level menu dropdown (e.g. References, Guides) — fires menu_toggle: <tab-id> for each

Login (login-button, user-menu)

  • Click login button in top nav (logged-out state) — fires top_nav: login
  • Click login button elsewhere — fires login_button (we don't use it anywhere else)

Breadcrumbs (breadcrumbs)

  • Click a breadcrumb link — fires breadcrumb_click: <position>/<total> (e.g. 2/3)

Table of Contents (generic-toc, reference-toc)

  • Click a TOC link on an article page — fires toc_click: #<id>
  • Click a TOC link on a reference page — fires toc_click: #<id>

Sidebar (sidebar-filter, hooks/glean-init.js)

  • Focus the sidebar filter input — fires sidebar_filter_focus
  • Type into the sidebar filter — fires sidebar_filter_typed (once, on first non-empty input)
  • Click any link in the left sidebar — fires sidebar_click: sidebar <href>

Footer (footer)

  • Click a social media icon (e.g. GitHub) — fires footer: social -> <icon>
  • Click a footer section link — fires footer: link -> <href>
  • Click a Mozilla-related footer link — fires footer: mozilla -> <href>

Language Switcher (language-switcher, language-always-redirect-button, translation-banner)

  • On a translated page, click a language link — fires language: <from> -> <to>
  • Toggle "remember preference" on — fires language_remember: <old> -> <locale>
  • Toggle "remember preference" off — fires language_remember: <old> -> 0
  • Click "Always redirect" button — fires language: <from> -> <to> (always)
  • Click "View in English" on translation banner — fires language: <locale> -> en-US (view)

Homepage (featured-articles, latest-news, recent-contributions)

  • Click a featured article tag — fires homepage: article_tag <n>
  • Click a featured article title — fires homepage: article <n>
  • Click a news source link — fires homepage: news_source <n>
  • Click a news item title — fires homepage: news <n>
  • Click a recent contribution link — fires homepage: contribution <n>

About Tabs (about-tabs)

  • Navigate to an About page and click a tab — fires about: tab -> <panel-id>

Playground (playground)

  • Click the Share button — fires playground: share-click
  • Click Reset and confirm — fires playground: reset-click
  • In share modal, click "Copy as Markdown" — fires playground: share-markdown
  • In share modal, click "Create permalink" — fires playground: share-permalink
  • Click the Report/Flag button — fires playground: flag-click
  • Click Login from share modal (logged-out state) — fires playground: banner-login

Collections (collection-save-button)

  • Click Save to Collection — fires article_actions_collections_opened
  • Open the collection select dropdown — fires article_actions_collection_select_opened
  • Select "Add new collection" — fires article_actions_new_collection
  • Submit saving to a collection — fires new_collection_modal_submit_article_actions

Observatory (observatory-form, observatory-results, observatory-results/rating)

  • Submit a scan — fires observatory: scan
  • Trigger a scan error — fires observatory: error -> <message>
  • Click Rescan — fires observatory: rescan
  • Click a results tab — fires observatory: tab -> <key>
  • Click "Scan another website" — fires observatory: scan-another
  • Trigger API failure for scan results — fires observatory: error -> Observatory API request for scan data failed (we'll catch this with Sentry in the future)

View/Impression Measurements (scroll into viewport, fires once)

  • Scroll a BCD table into view — fires bcd: view -> <query>
  • Scroll Scrimba placement banner into view — fires banner_scrimba_view
  • Scroll a Scrim inline embed into view — fires curriculum: scrim view id:<scrim-id>
  • Scroll curriculum partner banner into view — fires curriculum: partner banner view
  • Verify view measurements only fire once per element (scroll away and back)

Infrastructure (hooks/glean-init.js)

  • Verify data-glean-id attribute works on click
  • Verify data-glean-toggle-open fires only when a <details> element opens (not on close)
  • Verify data-glean-view fires once when element scrolls into 50% visibility
  • Verify external link clicks still fire external-link: <href>

@caugner
Copy link
Copy Markdown
Contributor Author

caugner commented Feb 11, 2026

  • Close the theme dropdown without changing — fires theme_switcher: close

🐛 Also fires when selecting an item.
🔥 Fires on page load.

  • Click each top-level menu dropdown (e.g. References, Guides) — fires menu_toggle: <tab-id> for each

🐛 Fires both on open and close.

  • Click login button in top nav (logged-out state) — fires top_nav: login
  • Click login button elsewhere — fires login_button

🐛 No event observed (maybe because the data-glean-id is on the mdn-button, not on the a inside).

  • Click "Always redirect" button — fires language: <from> -> <to> (always)

  • Click "View in English" on translation banner — fires language: <locale> -> en-US (view)

Need to test locally.

  • Click a news source link — fires homepage: news_source <n>

  • Click a news item title — fires homepage: news <n>

Need to test locally.

  • Click Reset and confirm — fires playground: reset-click

🐛 No event.

  • Open the collection select dropdown — fires article_actions_collection_select_opened

🐛 Fires when item is selected, not when the select is opened.

  • Scroll a Scrim inline embed into view — fires curriculum: scrim view id:<scrim-id>

Need to test locally.

caugner added 4 commits March 27, 2026 13:52
On first Lit render, `open` changes from `undefined` to `false`,
which was incorrectly triggering a `toggle` event and causing
`theme_switcher: close` (and similar) to fire on page load.
Selecting an option programmatically closes the dropdown, which was
incorrectly firing a `close` event in addition to the `switch` event.
The button's data-glean-id fired on every click (both open and close).
Moved tracking to data-glean-toggle-open on mdn-dropdown and extended
glean-init's toggle handler to support any element with an `open`
property (not only <details>).
@caugner
Copy link
Copy Markdown
Contributor Author

caugner commented Mar 27, 2026

  • Close the theme dropdown without changing — fires theme_switcher: close

🐛 Also fires when selecting an item. 🔥 Fires on page load.

✅ Fixed via ed7ff87.

  • Click each top-level menu dropdown (e.g. References, Guides) — fires menu_toggle: <tab-id> for each

🐛 Fires both on open and close.

✅ Fixed via 7cfb63b.

  • Click login button in top nav (logged-out state) — fires top_nav: login
  • Click login button elsewhere — fires login_button

🐛 No event observed (maybe because the data-glean-id is on the mdn-button, not on the a inside).

✅ Fixed via f738244.

  • Click "Always redirect" button — fires language: <from> -> <to> (always)
  • Click "View in English" on translation banner — fires language: <locale> -> en-US (view)

Need to test locally.

✅ Works as expected.

  • Click a news source link — fires homepage: news_source <n>
  • Click a news item title — fires homepage: news <n>

Need to test locally.

The news don't render locally, but those are just links, so I have high confidence that it works.

  • Click Reset and confirm — fires playground: reset-click

🐛 No event.

✅ Fixed via db8005f.

  • Open the collection select dropdown — fires article_actions_collection_select_opened

🐛 Fires when item is selected, not when the select is opened.

✅ Fixed via f857a2d.

  • Scroll a Scrim inline embed into view — fires curriculum: scrim view id:<scrim-id>

Need to test locally.

✅ Fixed via 2855bdd (didn't fire).

caugner added 2 commits March 27, 2026 15:14
data-glean-id on mdn-button is unreachable via closest() when the click
originates from the nested <a> inside mdn-button's shadow DOM. Using a
direct gleanClick call avoids the shadow boundary limitation.
The event was gated behind a controller null-check, so it could be
silently dropped. Fire gleanClick as soon as the user confirms the
dialog, independent of the controller reference.
@caugner caugner force-pushed the add-missing-measurements branch from d8c185e to 875f6ed Compare March 27, 2026 14:16
caugner added 2 commits March 27, 2026 16:03
The event was firing on the change event (item selected) rather than
when the select dropdown is opened. Moved it to focus on the select
element, which fires when the select gains focus (once per open action).
The dialog element is not visible in the viewport when the user hasn't opened it yet, so the IntersectionObserver never fired. Moving the ref to the body div ensures the element is in flow and observable.
@caugner caugner force-pushed the add-missing-measurements branch from 875f6ed to 2855bdd Compare March 27, 2026 15:04
@caugner caugner marked this pull request as ready for review March 27, 2026 15:09
@caugner caugner requested a review from a team as a code owner March 27, 2026 15:09
@caugner caugner requested a review from LeoMcA March 27, 2026 15:09
Comment thread components/playground/element.js
Copy link
Copy Markdown
Member

@LeoMcA LeoMcA left a comment

Choose a reason for hiding this comment

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

Still going through it, but one comment so far:

Comment thread components/button/element.js Outdated
Comment on lines +25 to +30
this.addEventListener("click", () => {
const gleanId = this.dataset.gleanId;
if (gleanId) {
gleanClick(gleanId);
}
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm interested why this is necessary, as I would've thought our shadow dom workaround code in glean-init.js would cover this case:

fred/hooks/glean-init.js

Lines 28 to 38 in 88f55bc

if (composedTarget !== event.target && composedTarget instanceof Element) {
// Workaround for automatic click events in shadow DOM.
// See: https://bugzil.la/1988206
const taggedElement = composedTarget.closest("[data-glean-id]");
if (taggedElement instanceof HTMLElement) {
const gleanId = taggedElement.dataset.gleanId;
if (gleanId) {
gleanClick(gleanId);
}
}
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The workaround works if the element with data-glean-id is inside the shadow DOM, but in this case the attribute is set on the host element, so closest() returns null.

I think this article describes this.

But we might be able to do something like this instead:

event.composedPath().find(el => el instanceof Element && el.matches(selector)) ?? null;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  • 4447fb7: Use composedPath() instead of closest()
  • 96da56f: Reverts the mdn-button click handler.
  • 3508870: Measure all data-glean-ids along the path (e.g. the login button in Playground should be measured both as login_button (via <mdn-login-button>) and playground: banner-login (via <mdn-playground>).

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.

3 participants