Skip to content

feat(analytics): add trackScreenView and trackScreenLeave public APIs - #439

Merged
rahul-mixpanel merged 10 commits into
masterfrom
rahulraveendran-sdk-119-add-trackscreenview-and-trackscreenleave-public-apis-to
Jul 21, 2026
Merged

feat(analytics): add trackScreenView and trackScreenLeave public APIs#439
rahul-mixpanel merged 10 commits into
masterfrom
rahulraveendran-sdk-119-add-trackscreenview-and-trackscreenleave-public-apis-to

Conversation

@rahul-mixpanel

Copy link
Copy Markdown
Contributor

Summary

  • Adds mixpanel.autocapture.trackScreenView(screenName, properties?) and mixpanel.autocapture.trackScreenLeave(screenName, properties?) public APIs, mirroring the native Android/Swift SDK interfaces
  • Implements native bridge methods for both Android (getAutocapture().trackScreenView/trackScreenLeave) and iOS (autocapture.trackScreenView/trackScreenLeave)
  • Adds JS-mode fallback in mixpanel-main.js for Expo/web environments (tracks $mp_page_view / $mp_page_leave with current_page_title and $mp_autocapture properties)
  • Updates sample app (MixpanelStarter) with navigation-based screen tracking using onReady and onStateChange

Changes

  • index.js — New Autocapture class with lazy getter on Mixpanel
  • index.d.ts — TypeScript definitions for Autocapture class
  • android/.../MixpanelReactNativeModule.javatrackScreenView and trackScreenLeave bridge methods
  • ios/MixpanelReactNative.swift — Swift bridge implementations
  • ios/MixpanelReactNative.m — ObjC extern method declarations
  • javascript/mixpanel-main.js — JS-mode fallback implementation
  • Samples/MixpanelStarter/src/App.tsx — Sample app screen tracking

Test plan

  • All 291 unit tests pass
  • Manual test on Android emulator — verify $mp_page_view and $mp_page_leave events fire on tab navigation
  • Manual test on iOS simulator — verify events fire on tab navigation
  • Verify current_page_title and $mp_autocapture properties are set by native SDK (not duplicated in JS layer)

Closes SDK-119

…ccessor

Add new Autocapture class exposing trackScreenView and trackScreenLeave
methods, matching the native Android/Swift SDK pattern
(mixpanel.autocapture.trackScreenView/trackScreenLeave).

- JS API: new Autocapture class with lazy getter on Mixpanel
- TypeScript definitions for Autocapture class
- Android bridge: delegates to instance.getAutocapture()
- iOS bridge: delegates to instance.autocapture
- JS-mode fallback: pure JS implementation
- Sample app: NavigationContainer onStateChange tracking

Ref: SDK-119
The autocapture getter was incorrectly placed between the flush()
JSDoc comment and the flush() method. Moved it next to the flags
getter for proper code organization.
…layer

These properties are already set by the native SDK in
getAutocapture().trackScreenView/trackScreenLeave. Only the JS-mode
fallback (mixpanel-main.js) needs to set them since it bypasses native.
@linear-code

linear-code Bot commented Jul 15, 2026

Copy link
Copy Markdown
@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

Safe to merge — the change is additive, all three paths (native Android, native iOS, JS fallback) are correctly guarded, and the sample app's dual-path race-condition fix works as designed.

The new Autocapture API is self-contained and additive. The Android bridge correctly null-checks getAutocapture() before calling through. The iOS bridge uses optional chaining consistent with all existing bridge methods. The JS fallback correctly sets the expected event name and properties. No existing behavior is modified.

No files require special attention.

Important Files Changed

Filename Overview
index.js Adds Autocapture class with trackScreenView/trackScreenLeave; lazy getter on Mixpanel; consistent with existing Flags pattern
ios/MixpanelReactNative.swift Adds Swift bridge for trackScreenView/trackScreenLeave; optional chaining on instance is consistent with rest of file
android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java Adds Java bridge methods with proper null-check on getAutocapture() and promise resolution
javascript/mixpanel-main.js Adds JS-mode fallback for trackScreenView/trackScreenLeave, correctly setting current_page_title and $mp_autocapture
Samples/MixpanelStarter/src/App.tsx Splits AppNavigator out of App; uses dual-path (onReady + useEffect) to handle the race between nav readiness and Mixpanel init
index.d.ts Adds Autocapture TypeScript class and readonly autocapture property to Mixpanel
Samples/MixpanelStarter/metro.config.js Updates blockList regex to allow json-logic-js and base-64 through from parent node_modules

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant App as App.tsx
    participant AC as Autocapture (index.js)
    participant NativeImpl as MixpanelReactNative (Native)
    participant JSImpl as MixpanelMain (JS fallback)
    participant Android as Android SDK
    participant iOS as iOS SDK

    App->>AC: mixpanel.autocapture.trackScreenView(screenName)
    AC->>AC: validate screenName
    AC->>AC: merge getMetaData() + properties

    alt Native mode (iOS/Android)
        AC->>NativeImpl: trackScreenView(token, screenName, props)
        NativeImpl->>Android: getAutocapture().trackScreenView(screenName, props)
        NativeImpl->>iOS: autocapture.trackScreenView(screenName, props)
    else JS mode (Expo/Web)
        AC->>JSImpl: trackScreenView(token, screenName, props)
        JSImpl->>JSImpl: merge current_page_title and $mp_autocapture
        JSImpl->>JSImpl: track($mp_page_view, mergedProps)
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant App as App.tsx
    participant AC as Autocapture (index.js)
    participant NativeImpl as MixpanelReactNative (Native)
    participant JSImpl as MixpanelMain (JS fallback)
    participant Android as Android SDK
    participant iOS as iOS SDK

    App->>AC: mixpanel.autocapture.trackScreenView(screenName)
    AC->>AC: validate screenName
    AC->>AC: merge getMetaData() + properties

    alt Native mode (iOS/Android)
        AC->>NativeImpl: trackScreenView(token, screenName, props)
        NativeImpl->>Android: getAutocapture().trackScreenView(screenName, props)
        NativeImpl->>iOS: autocapture.trackScreenView(screenName, props)
    else JS mode (Expo/Web)
        AC->>JSImpl: trackScreenView(token, screenName, props)
        JSImpl->>JSImpl: merge current_page_title and $mp_autocapture
        JSImpl->>JSImpl: track($mp_page_view, mergedProps)
    end
Loading

Reviews (6): Last reviewed commit: "Keep defensive validation in mixpanel-ma..." | Re-trigger Greptile

Comment thread android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java Outdated
Comment thread Samples/MixpanelStarter/src/App.tsx
…ew race condition

Add defensive null checks around getAutocapture() in Android bridge to
prevent potential NPE. Fix sample app to handle the case where Mixpanel
initializes after the navigation container mounts, ensuring the initial
screen view event is always tracked. Also fix Metro config to allow SDK
dependencies (json-logic-js, base-64) through the parent blockList.
@rahul-mixpanel rahul-mixpanel changed the title Add trackScreenView and trackScreenLeave public APIs Jul 16, 2026
@rahul-mixpanel
rahul-mixpanel marked this pull request as ready for review July 17, 2026 10:48
@rahul-mixpanel
rahul-mixpanel requested review from a team and jakewski July 17, 2026 10:48
@ketanmixpanel
ketanmixpanel requested a review from Copilot July 20, 2026 06:57

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 a new public Autocapture surface to the Mixpanel React Native SDK for screen view/leave tracking, aligning the JS API with native Android/Swift SDK interfaces and providing a JS-mode fallback for Expo/web usage.

Changes:

  • Introduces mixpanel.autocapture.trackScreenView(...) and mixpanel.autocapture.trackScreenLeave(...) as public APIs (JS + TypeScript types).
  • Implements the corresponding native bridge methods on Android and iOS, plus a JS-mode fallback that emits $mp_page_view / $mp_page_leave.
  • Updates the MixpanelStarter sample to track screen view/leave from React Navigation state changes; adjusts Metro config to resolve SDK-only deps from the parent package.

Reviewed changes

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

Show a summary per file
File Description
index.js Adds autocapture lazy getter on Mixpanel and the new Autocapture class wrapper that delegates to the active implementation.
index.d.ts Exposes Autocapture and the Mixpanel.autocapture property in TypeScript typings.
android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java Adds React Native bridge methods for trackScreenView / trackScreenLeave using Android SDK autocapture.
ios/MixpanelReactNative.swift Adds Swift bridge implementations for trackScreenView / trackScreenLeave.
ios/MixpanelReactNative.m Exports the new Swift bridge methods to React Native via RCT_EXTERN_METHOD.
javascript/mixpanel-main.js Adds JS-mode fallback that tracks $mp_page_view / $mp_page_leave with current_page_title and $mp_autocapture.
Samples/MixpanelStarter/src/App.tsx Implements navigation-driven screen view/leave tracking via onReady and onStateChange.
Samples/MixpanelStarter/metro.config.js Tweaks Metro resolution/blockList to allow specific parent node_modules deps and map them via extraNodeModules.
Comment thread javascript/mixpanel-main.js
Comment thread index.js
Comment thread Samples/MixpanelStarter/metro.config.js Outdated
Copilot AI and others added 2 commits July 20, 2026 10:06
Comment thread javascript/mixpanel-main.js
…Leave

Log via MixpanelLogger.warn when screenName is blank or non-string,
matching the logging pattern used across other SDK methods and aligning
with the Flutter SDK's validation logging.
Comment thread javascript/mixpanel-main.js
Comment thread index.js
Consolidate validation + warning logging for trackScreenView and
trackScreenLeave into index.js (public API) and remove redundant
checks from mixpanel-main.js, since the impl is only called after
validation has already passed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ketanmixpanel
ketanmixpanel previously approved these changes Jul 21, 2026
Restore screenName validation in trackScreenView/trackScreenLeave
in mixpanel-main.js for defensive safety, but without the
MixpanelLogger.warn calls since logging is now handled at the
public API layer in index.js.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rahul-mixpanel
rahul-mixpanel merged commit cfe9110 into master Jul 21, 2026
10 checks passed
@rahul-mixpanel
rahul-mixpanel deleted the rahulraveendran-sdk-119-add-trackscreenview-and-trackscreenleave-public-apis-to branch July 21, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants