feat(frontend): track main navigation section visits in Plausible#13168
Draft
sbpublic wants to merge 15 commits into
Draft
feat(frontend): track main navigation section visits in Plausible#13168sbpublic wants to merge 15 commits into
sbpublic wants to merge 15 commits into
Conversation
Spec for tracking page_open visits across the five main navigation sections (Assets, Activity, Earn, Explore, Settings) plus completing the Assets sub-tab view_open counts with an auto/click event_trigger. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds page-visit event_value/event_context members for the five main nav sections, the auto/click PLAUSIBLE_EVENT_TRIGGERS enum, and a shared buildAssetsTabViewEvent factory so the click and landing view_open fires stay byte-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Composed from the existing isTokensPath/isNftsPath/isEarningPath predicates to tell "entering the Assets section" from an intra-section sub-tab switch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirror the existing Earn onMount PAGE_OPEN pattern in each single-route section's feature component so a section visit is counted however it is reached (nav click, direct URL, back/forward, redirect). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the inline view_open object in Tabs.handleClick with
buildAssetsTabViewEvent({ trigger: click }); preserves the existing
assets_tab / assets_page semantics and adds event_trigger.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entry-guarded afterNavigate fires page_open (assets-page) plus an auto view_open for the landing tab only when arriving from a non-Assets route, so sub-tab switches (already counted by Tabs) are not double-counted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…changes Formatter/linter output only: prettier on the spec + Assets.svelte and eslint import-order on Settings.svelte / AllTransactions.svelte. No behaviour change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- page_open on mount for Activity, Explore, Settings, Rewards - Assets entry-guard: page_open + auto view_open on section entry, neither on intra-Assets sub-tab switches, landing tab parametrised - Tabs click fires view_open with event_trigger=click - buildAssetsTabViewEvent helper (auto + click payloads) - isAssetsRouteId true/false cases Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Folds the generic ui_click event (main nav menu + Assets tab bar) into the existing spec: schema, helper, instrumentation steps, tests, acceptance, and out-of-scope (orthogonal to page_open; standard source_location key; legacy location_source migration deferred). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the generic UI_CLICK event and a NAVIGATION source_location member (standard source_location key), plus a buildUiClickEvent factory so navigation click payloads stay centralised and consistent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds an optional trackEvent prop to NavigationItem (fired on click, mirroring ExternalLink) and wires each main-menu item to a ui_click with source_location=navigation, source_sublocation=main_menu, and the section id as event_value. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A sub-tab click now fires the generic ui_click (source_sublocation= assets_tabs) alongside the existing view_open(trigger=click); the two are complementary UI-interaction and appearance signals. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- buildUiClickEvent payloads (with and without sublocation/value) - NavigationItem fires/omits trackEvent on click per prop presence - Tabs click fires both view_open(click) and ui_click Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
We want to see which of the main navigation sections users actually use and how that shifts over time. Today only Earn emits a section-visit event; Assets, Activity, Explore, Settings (and the Rewards fallback) emit nothing. The Assets sub-tabs also have a default-tab-biased blind spot:
view_openfired only on a tab click, so the tab a user lands on was never counted.This implements the spec
docs/ai/spec-driven-development/specs/2026-06-22-impr-track-nav-section-visits.md(authored via the spec-driven workflow), extending the existing EarnPAGE_OPENpattern to every section and completing the per-tab view counts. It also adds a genericui_clickevent for navigation interactions (main nav menu + Assets tab bar) — the complementary "how users navigate" signal alongsidepage_open's "which sections get visited" count.Changes
plausible.ts): addsassets-page/activity-page/explore-page/settings-page/rewards-pagetoPLAUSIBLE_EVENT_VALUES, the matching sectionPLAUSIBLE_EVENT_CONTEXTS, a newPLAUSIBLE_EVENT_TRIGGERSenum (auto/click), theUI_CLICKevent, and aNAVIGATIONmember onPLAUSIBLE_EVENT_SOURCE_LOCATIONS(the standardsource_locationenum).analytics.services.ts):buildAssetsTabViewEvent()(shared by the click and landingview_openfires) andbuildUiClickEvent()(navigation click payloads); plusisAssetsRouteId()innav.utils.ts(composed from the existing path predicates).onMountPAGE_OPENinAllTransactions.svelte(Activity),DappsExplorer.svelte(Explore),Settings.svelte, andRewards.svelte— mirroring Earn, which is left untouched. A visit counts however the section is reached (nav click, direct URL, back/forward, redirect).Assets.svelte): an entry-guardedafterNavigatefirespage_open(assets-page) plus a landingview_open(event_trigger = auto) only when arriving from a non-Assets route, so sub-tab switches are not double-counted.Tabs.svelte): the clickview_openis routed throughbuildAssetsTabViewEvent({ trigger: click })(preserving theassets_tab/assets_pagesemantics, addingevent_trigger), and now also fires aui_click(source_sublocation = assets_tabs).NavigationItem.svelte/NavigationMenuMainItems.svelte):NavigationItemgains an optionaltrackEventprop (fired on click, mirroringExternalLink); each menu item emitsui_clickwithsource_location = navigation,source_sublocation = main_menu, and the section id asevent_value.PRODUCT.md: documents the section-visit, Assets sub-tab, andui_clicknavigation analytics (updated in this PR, per the workflow).Tests
NavigationItem; addedpage_opencases to the existing Activity (AllTransactions) andSettingsspecs.Assets.spec.ts: entry from a non-Assets route (and initial load,from === null) firespage_open+autoview_open; intra-Assets sub-tab switches fire neither; theautoevent_valuematches the landing tab (parametrised over tokens / nfts / earning).Tabs.spec.ts: a click fires bothview_open(event_trigger = click) andui_click(source_sublocation = assets_tabs).NavigationItem.spec.ts: clicking fires the providedtrackEvent; nothing fires when the prop is absent.buildAssetsTabViewEvent(both triggers),buildUiClickEvent(with and without sublocation/value), andisAssetsRouteId(true for tokens/nfts/earning ids, false for the rest andnull).formatandlint --max-warnings 0pass clean.checkand the fulltestsuite have only pre-existing, unrelated failures locally (dependency-version skew in untouchedsol/ic-pub-keyfiles; the known jsdom/localStorageAllTransactionssessionStorage flake that reproduces onmain); both are left to CI.Divergence from the spec
No material divergence — the implementation follows the spec section by section.
buildAssetsTabViewEventhelper hardcodes theview_openevent name, soTabs' generictrackEventNameprop now acts purely as an enable-flag (its value no longer sets the emitted event name). The Assets sub-tabs are its only tracked consumer today.ui_clickevent was added after a follow-on PM decision and folded into this PR (it deliberately does not addevent_triggertopage_open, which stays the complete "visits however reached" metric). It uses the standardsource_locationkey; migrating the legacylocation_sourceonview_openis left as separate, step-by-step cleanup.🤖 Generated with Claude Code — model: Claude Opus 4.8 (claude-opus-4-8)