Skip to content

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

Open
rahul-mixpanel wants to merge 4 commits into
masterfrom
rahulraveendran-sdk-119-add-trackscreenview-and-trackscreenleave-public-apis-to
Open

feat(analytics): add trackScreenView and trackScreenLeave public APIs#439
rahul-mixpanel wants to merge 4 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

SDK-119

@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

Safe to merge — all three paths (native Android, native iOS, JS fallback) are guarded against null instances and follow the established bridge patterns.

The new Autocapture class closely mirrors the existing Flags and People implementations, the Android bridge correctly null-checks getAutocapture(), the iOS bridge uses consistent optional chaining, and the JS fallback correctly pins the autocapture properties so they cannot be overridden by callers.

No files require special attention.

Important Files Changed

Filename Overview
index.js Adds Autocapture class (exported) with lazy-loaded getter on Mixpanel; follows existing Flags/People patterns closely.
index.d.ts Adds Autocapture TypeScript class and readonly autocapture: Autocapture on Mixpanel; consistent with Flags type declaration pattern.
android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java Adds trackScreenView and trackScreenLeave bridge methods; correctly null-checks both the instance and getAutocapture() before delegating.
ios/MixpanelReactNative.swift Adds Swift bridge methods using optional chaining on instance; consistent with existing track/timeEvent methods in the file.
ios/MixpanelReactNative.m Adds two RCT_EXTERN_METHOD declarations for the new Swift bridge methods; signatures match the Swift implementations.
javascript/mixpanel-main.js Adds JS-mode fallback tracking $mp_page_view/$mp_page_leave with current_page_title and $mp_autocapture properties hardcoded after any user properties.
Samples/MixpanelStarter/src/App.tsx Refactors navigation into AppNavigator and adds screen tracking via onReady/onStateChange + a useEffect fallback that handles the async Mixpanel init race.
Samples/MixpanelStarter/metro.config.js Allows json-logic-js and base-64 through the parent-package node_modules block-list and adds explicit extraNodeModules entries for them.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant App as App.tsx
    participant AC as Autocapture (index.js)
    participant Impl as mixpanelImpl
    participant NB as Native Bridge
    participant SDK as Native SDK

    App->>AC: mixpanel.autocapture.trackScreenView(name)
    AC->>AC: validate screenName + merge getMetaData()
    alt Native mode
        AC->>NB: MixpanelReactNative.trackScreenView(token, name, props)
        NB->>NB: appendLibraryProperties()
        NB->>SDK: getAutocapture().trackScreenView(name, props)
        Note over NB,SDK: null-checked (Android) / optional chain (iOS)
    else JS / Expo mode
        AC->>Impl: MixpanelMain.trackScreenView(token, name, props)
        Impl->>Impl: merge current_page_title + $mp_autocapture
        Impl->>Impl: 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 Impl as mixpanelImpl
    participant NB as Native Bridge
    participant SDK as Native SDK

    App->>AC: mixpanel.autocapture.trackScreenView(name)
    AC->>AC: validate screenName + merge getMetaData()
    alt Native mode
        AC->>NB: MixpanelReactNative.trackScreenView(token, name, props)
        NB->>NB: appendLibraryProperties()
        NB->>SDK: getAutocapture().trackScreenView(name, props)
        Note over NB,SDK: null-checked (Android) / optional chain (iOS)
    else JS / Expo mode
        AC->>Impl: MixpanelMain.trackScreenView(token, name, props)
        Impl->>Impl: merge current_page_title + $mp_autocapture
        Impl->>Impl: track("$mp_page_view", mergedProps)
    end
Loading

Reviews (2): Last reviewed commit: "fix: add null guard for getAutocapture()..." | 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 feat(analytics): 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
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.

1 participant