Skip to content

Track chat, search, auth, and dataplayer events in Matomo - #143

Merged
ritwikshanker merged 3 commits into
mainfrom
update-matomo
Aug 20, 2026
Merged

ritwikshanker merged 3 commits into
mainfrom
update-matomo

Conversation

@ritwikshanker

@ritwikshanker ritwikshanker commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

This pull request significantly enhances analytics and event tracking throughout the application, focusing on improved Matomo integration, more granular event reporting, and robust testing. The changes introduce event tracking for user actions like file previews, downloads, authentication flows, error boundaries, and search result interactions, while also adding comprehensive tests for the analytics utilities.

Analytics and Event Tracking Improvements

  • Added Matomo event tracking to key user interactions, including file preview openings, preview failures, downloads, authentication completions, and error boundaries, providing more detailed insight into user behavior. [1] [2] [3] [4] [5]
  • Enhanced search analytics by tracking search result counts, latency, zero-result occurrences, and errors, and by reporting site searches with associated hit counts.
  • Improved Matomo pageview and site search tracking logic to avoid double-counting and to distinguish between pageviews and search result events.

Testing and Utility Enhancements

  • Added comprehensive tests for analytics utilities, covering event tracking, site search keyword extraction, and error categorization.
  • Introduced tests for the MatomoTracker component to verify correct event dispatching in various navigation and search scenarios.

Codebase and Dependency Updates

  • Refactored the useMatomo hook to provide a stable, module-level trackEvent function for safe use in dependency arrays.
  • Updated analytics utility types and improved documentation for better maintainability and clarity.

These changes collectively provide more actionable analytics, improve the accuracy of event reporting, and ensure the analytics layer is robustly tested and easier to maintain.The chat and dataplayer flows had no instrumentation at all, and search recorded only that a query was submitted, never its outcome. Adds:

  • Chat: message_sent, tool_call, run_latency_ms, results_returned, run_error
  • Search: results_returned, latency_ms, zero_results, error
  • Auth: login_completed, closing the funnel opened by gate_triggered
  • Dataplayer: tool_selected, run_submitted, run_succeeded, run_failed
  • FilePreview: opened, downloaded, failed
  • Error: react_boundary and route_error, so client crashes are counted

Moves the _paq push into lib/analytics.ts so the class-based ErrorBoundary can reach it, leaving useMatomo a thin wrapper. Fixes a positional bug there: a value passed without a name landed in the name column.

Also enables Matomo's heartbeat timer. Without it time-on-page is derived from the gap between pageviews, so the last page of every visit counted as zero seconds.

The chat and dataplayer flows had no instrumentation at all, and search
recorded only that a query was submitted, never its outcome. Adds:

- Chat: message_sent, tool_call, run_latency_ms, results_returned, run_error
- Search: results_returned, latency_ms, zero_results, error
- Auth: login_completed, closing the funnel opened by gate_triggered
- Dataplayer: tool_selected, run_submitted, run_succeeded, run_failed
- FilePreview: opened, downloaded, failed
- Error: react_boundary and route_error, so client crashes are counted

Moves the _paq push into lib/analytics.ts so the class-based ErrorBoundary
can reach it, leaving useMatomo a thin wrapper. Fixes a positional bug
there: a value passed without a name landed in the name column.

Also enables Matomo's heartbeat timer. Without it time-on-page is derived
from the gap between pageviews, so the last page of every visit counted as
zero seconds.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds comprehensive Matomo instrumentation across key user flows (chat, search, auth, dataplayer, file preview) and centralizes event pushing into a shared analytics helper so both hooks and class-based boundaries can track events consistently. Also enables Matomo heartbeat tracking to improve time-on-page accuracy.

Changes:

  • Introduces src/lib/analytics.ts (trackEvent, errorKind) and updates useMatomo to wrap the shared helper.
  • Adds new events for Chat, Search, Auth, Dataplayer, FilePreview, and client crash tracking (React error boundary + route error boundary).
  • Enables Matomo enableHeartBeatTimer to improve engagement metrics.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/root.tsx Adds route-level error tracking via Matomo in the router ErrorBoundary.
src/pages/DataplayerPage.tsx Tracks dataplayer tool selection and run outcomes (submitted/succeeded/failed) with latency.
src/pages/ChatPage.tsx Adds chat funnel instrumentation: message sent, tool calls, run latency, results count, and errors.
src/lib/analytics.ts New module-level Matomo helper (trackEvent) plus stable error labeling (errorKind).
src/lib/analytics.test.ts Adds unit tests for Matomo positional args and errorKind classification.
src/hooks/useSearchResults.ts Tracks search outcomes (results count, latency, zero results, error) in addition to submission.
src/hooks/useMatomo.ts Refactors hook into a thin wrapper around the shared trackEvent helper.
src/hooks/useAuth.ts Tracks Auth/login_completed to close the gate-triggered funnel without leaking query strings.
src/components/MatomoTracker.tsx Enables Matomo heartbeat timer for better time-on-page measurement.
src/components/ErrorBoundary.tsx Adds tracking for React render crashes from the class-based boundary.
src/components/dataplayer/FilePreviewModal.tsx Tracks preview opens, downloads, and failures with status classification.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/root.tsx
Comment thread src/components/ErrorBoundary.tsx
Comment thread src/lib/analytics.ts
Site search is already enabled on site id 10 and Matomo auto-detects the
`q` parameter, so /search?q=... is counted as a search today — this is
where the 693 searches in the last report came from. What it cannot know
that way is how many results came back, which is why "Search Keywords with
No Results" is empty.

useSearchResults now reports the search explicitly with its hit count, and
MatomoTracker holds back the pageview for that navigation, since Matomo
counts a site search instead of a pageview rather than as well as one. The
action count per visit is unchanged.

The suppression is keyed on the keyword, not the route, because filtering
is client-side: the URL changes but useSearchResults does not re-run, so
suppressing on every /search URL would lose those actions entirely. A
filter change still sends the pageview and is still detected as a search
from `q`, which is how it has always been counted.

A failed search falls back to the pageview rather than reporting zero
hits, which would otherwise file it under no-result keywords.
Addresses review on #143. Both error boundaries were sending
error.message as the event name. Messages from this app can carry a
dataset title, a file path or a query the user typed, and every distinct
one becomes its own row in the Events report. Both now send the
constructor name, with route responses still reported by status code.
Full detail stays in the console via logError.

Also drops an unsound cast in the analytics push helper. The helper does
need to accept booleans — trackSiteSearch passes `false` for an omitted
category — so rather than narrowing the parameter, the _paq global is
widened to match Matomo's actual command vocabulary and the cast goes
away. Narrowing instead fails to compile on the trackSiteSearch call.
@ritwikshanker
ritwikshanker merged commit 83960c3 into main Aug 20, 2026
6 checks passed
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.

2 participants