Skip to content

fix(analytics): keep frontend metadata separate from optional arguments - #2649

Open
creeperkatze wants to merge 5 commits into
wxt-dev:mainfrom
creeperkatze:fix/analytics-frontend-metadata
Open

creeperkatze wants to merge 5 commits into
wxt-dev:mainfrom
creeperkatze:fix/analytics-frontend-metadata

Conversation

@creeperkatze

Copy link
Copy Markdown
Contributor

Overview

Calls from the popup, options pages or content scripts that left out an optional argument, like track('some-event') or identify('some-user-id') from the README, received the page metadata in that argument's place. The metadata is now sent as its own field.

Manual Testing

  1. In the demo popup (packages/analytics/entrypoints/popup/main.ts), add void analytics.track('no-props');.
  2. Run bun run dev:build in packages/analytics and load .output/chrome-mv3 in Chrome.
  3. Open the popup and check the background's console. The logged track event should have no properties, and meta should have the popup's URL and a session ID. Before this change, the metadata showed up in event.properties and meta.url was background.js.

@netlify

netlify Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for creative-fairy-df92c4 ready!

Name Link
🔨 Latest commit 9c40f9a
🔍 Latest deploy log https://app.netlify.com/projects/creative-fairy-df92c4/deploys/6acdb5d7c224562b687a2d8d
😎 Deploy Preview https://deploy-preview-2649--creative-fairy-df92c4.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f2c9155b-ac8a-4658-9640-c0bf79c3d452

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c9c9d681-ec87-4727-b97f-756203c7f78c
📥 Commits

Reviewing files that changed from the base of the PR and between 6ee6031 and a0f7d09.

📒 Files selected for processing (1)
  • packages/analytics/modules/analytics/client.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough
📝 Walkthrough

Walkthrough

Analytics messages now carry event metadata separately from method arguments. The background port handler explicitly dispatches analytics methods and passes metadata to event methods in the correct parameter position.

Changes

Analytics metadata forwarding

Layer / File(s) Summary
Message shape and dispatch
packages/analytics/modules/analytics/client.ts
AnalyticsMessage now includes a separate meta field. The frontend forwarder sends metadata separately from args. The background port handler explicitly dispatches identify, page, track, captureException, and setEnabled.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to a0f7d

The metadata forwarding change is ready to merge after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to a0f7d

The change corrects metadata placement while preserving the observed opt-out controls and narrowing method dispatch. Compatibility between clients running different versions remains unverified, so the assessment is low risk rather than risk-free.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — A caller able to open the matching internal analytics port can affect the background’s shared analytics identity and enabled flag, and submit events to configured providers when enabled. The inspected path does not establish reachability from arbitrary websites, other extensions, tenants, or services.

Trust Boundaries and Controls

  • observed — The listener remains browser.runtime.onConnect and routes by port name; no new external connection listener is introduced. Additional sender authorization and runtime payload validation are absent in both inspected versions. Explicit method dispatch narrows the former dynamic lookup, while provider enabled checks remain intact. These existing boundary limitations were not shown to gain new exposure or authority through this PR.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: keeping frontend metadata separate from optional analytics arguments.
Description check ✅ Passed The description includes an overview and concrete manual testing steps with expected results. The template’s Related Issue section is omitted, but it is conditional and does not prevent the descriptio…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the pkg/analytics Includes changes to the `packages/analytics` directory label Oct 4, 2026
@creeperkatze

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@PatrykKuniczak PatrykKuniczak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it can be simplified.

But again, so sorry, but i don't understand, and don't see difference:

Before:
Image

After:
Image

After all, it seems it's breaking change and it's not fix it's feat/chore.

Let's send me more details please.

Comment on lines +270 to +292
port.onMessage.addListener((message: AnalyticsMessage) => {
const { meta } = message;
// Pass every argument explicitly, so meta doesn't shift into an omitted optional one
switch (message.fn) {
case 'identify':
return void analytics.identify(
message.args[0],
message.args[1],
meta,
);
case 'page':
return void analytics.page(message.args[0], meta);
case 'track':
return void analytics.track(message.args[0], message.args[1], meta);
case 'captureException':
return void analytics.captureException(
message.args[0],
message.args[1],
meta,
);
case 'setEnabled':
return void analytics.setEnabled(message.args[0]);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
port.onMessage.addListener((message: AnalyticsMessage) => {
const { meta } = message;
// Pass every argument explicitly, so meta doesn't shift into an omitted optional one
switch (message.fn) {
case 'identify':
return void analytics.identify(
message.args[0],
message.args[1],
meta,
);
case 'page':
return void analytics.page(message.args[0], meta);
case 'track':
return void analytics.track(message.args[0], message.args[1], meta);
case 'captureException':
return void analytics.captureException(
message.args[0],
message.args[1],
meta,
);
case 'setEnabled':
return void analytics.setEnabled(message.args[0]);
}
port.onMessage.addListener((message: AnalyticsMessage) => {
const { meta, fn } = message;
// Pass every argument explicitly, so meta doesn't shift into an omitted optional one
switch (fn) {
case 'identify':
return analytics.identify(
message.args[0],
message.args[1],
meta,
);
case 'page':
return analytics.page(message.args[0], meta);
case 'track':
return analytics.track(message.args[0], message.args[1], meta);
case 'captureException':
return analytics.captureException(
message.args[0],
message.args[1],
meta,
);
case 'setEnabled':
return analytics.setEnabled(message.args[0]);
}

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.

Thanks, applied your suggestion and fixed the conflict!

Button 1 goes through autoTrack, which always passes properties, so the bug doesn't show there. It only happens when you leave out an optional argument, like the analytics.track('some-event') example from the README.

Try adding void analytics.track('some-event') to the demo popup. Before this PR, the event's properties end up being the popup's metadata and meta.url is background.js. After, it's correct.

Not a breaking change since the public API stays the same. Only the internal message between the popup and the background changes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg/analytics Includes changes to the `packages/analytics` directory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants