From 319485e73be38bcfd5a268db2b72ccdc80262a09 Mon Sep 17 00:00:00 2001 From: Anna Garcia Date: Wed, 28 Oct 2026 19:07:15 -0400 Subject: [PATCH 1/3] chore(react-native-plugin)!: require posthog-android 4.0 --- .changeset/rn-plugin-v3-posthog-android-4.md | 5 +++++ packages/react-native-plugin/android/build.gradle | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/rn-plugin-v3-posthog-android-4.md diff --git a/.changeset/rn-plugin-v3-posthog-android-4.md b/.changeset/rn-plugin-v3-posthog-android-4.md new file mode 100644 index 0000000000..ee6264e44b --- /dev/null +++ b/.changeset/rn-plugin-v3-posthog-android-4.md @@ -0,0 +1,5 @@ +--- +'@posthog/react-native-plugin': major +--- + +**Breaking:** require posthog-android 4.0 diff --git a/packages/react-native-plugin/android/build.gradle b/packages/react-native-plugin/android/build.gradle index e5d3ddea8c..7f08d57db6 100644 --- a/packages/react-native-plugin/android/build.gradle +++ b/packages/react-native-plugin/android/build.gradle @@ -67,7 +67,7 @@ dependencies { // The React Native Gradle plugin provides the version. implementation "com.facebook.react:react-android" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation "com.posthog:posthog-android:3.74.2" + implementation "com.posthog:posthog-android:4.0.0" testImplementation "junit:junit:4.13.2" testImplementation "org.json:json:20250517" From f0dba7f9c558a3086e0123a286c3ef70f7e94b00 Mon Sep 17 00:00:00 2001 From: Anna Garcia Date: Fri, 30 Oct 2026 22:05:28 -0400 Subject: [PATCH 2/3] docs(react-native-plugin): fold posthog-android 4.0 notes into the 3.0 changeset and guide --- .changeset/rn-plugin-v3-posthog-android-4.md | 5 ----- .changeset/rn-plugin-v3.md | 1 + packages/react-native-plugin/MIGRATION.md | 22 +++++++++++--------- 3 files changed, 13 insertions(+), 15 deletions(-) delete mode 100644 .changeset/rn-plugin-v3-posthog-android-4.md diff --git a/.changeset/rn-plugin-v3-posthog-android-4.md b/.changeset/rn-plugin-v3-posthog-android-4.md deleted file mode 100644 index ee6264e44b..0000000000 --- a/.changeset/rn-plugin-v3-posthog-android-4.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@posthog/react-native-plugin': major ---- - -**Breaking:** require posthog-android 4.0 diff --git a/.changeset/rn-plugin-v3.md b/.changeset/rn-plugin-v3.md index 365aa6609b..c426199635 100644 --- a/.changeset/rn-plugin-v3.md +++ b/.changeset/rn-plugin-v3.md @@ -12,5 +12,6 @@ Release `@posthog/react-native-plugin` 3.0, with the upgrade steps in the [migra - **Breaking:** remove the legacy `start()` method — call `setup()` instead - **Breaking:** ignore `iOSdebouncerDelayMs` and `androidDebouncerDelayMs` when calling `setup()` directly — pass `throttleDelayMs` instead - **Breaking:** ignore the experimental iOS session replay option `screenshotModeBackgroundCapture` +- **Breaking:** require posthog-android 4.0 - Accept `projectToken` as well as `apiKey` in `setup()` options on Android - Treat the plugin's `start()` method as optional in `posthog-react-native` diff --git a/packages/react-native-plugin/MIGRATION.md b/packages/react-native-plugin/MIGRATION.md index f2a049107d..fc80ba7b01 100644 --- a/packages/react-native-plugin/MIGRATION.md +++ b/packages/react-native-plugin/MIGRATION.md @@ -11,7 +11,7 @@ If you only use the plugin through `posthog-react-native`, you don't need any Ja | macOS deployment target | 10.15 | 11.0 | | How `posthog-ios` is installed | CocoaPods trunk, or Swift Package Manager with `posthog.useSpm` | Swift Package Manager | -Android `minSdk` stays at 23. `posthog-react-native` still accepts this plugin through its optional `>= 2.12.7` peer range, and 4.47.0 is the first version that loads the plugin. +Android `minSdk` stays at 23, and the plugin now requires `posthog-android` 4.0. `posthog-react-native` still accepts this plugin through its optional `>= 2.12.7` peer range, and 4.47.0 is the first version that loads the plugin. Expo SDK 52 is the first Expo SDK that meets the React Native and iOS requirements. The Expo config plugin needs no changes. @@ -63,6 +63,10 @@ The plugin is still a CocoaPod, but it no longer depends on the `PostHog` pod. R - **Custom dSYM upload scripts can stop working.** `${PODS_ROOT}/PostHog/build-tools/upload-symbols.sh` no longer exists. Use `${BUILD_DIR%/Build/*}/SourcePackages/checkouts/posthog-ios/build-tools/upload-symbols.sh`. The `uploadNativeSymbols` build phase from the Expo config plugin already checks both paths. - **Remove `posthog-react-native-session-replay` if you still have it.** Its pod brings in `posthog-ios` from CocoaPods alongside the plugin's Swift package, and that combination is untested. +### `posthog-android` 4.0 + +If native code in your app calls `posthog-android` directly, it must handle the 4.0 API removals listed in the `posthog-android` changelog. + ## API changes These apply only if your code calls the plugin directly. @@ -101,21 +105,19 @@ sdkReplayConfig: { throttleDelayMs: 500 } ### `screenshotModeBackgroundCapture` is ignored on iOS -This experimental option no longer has any effect, and screenshots are captured on the main thread. `posthog-react-native` still accepts the option, so nothing warns you. Remove it from `sessionReplayConfig`. - -## New in 3.0 - -- Android `setup()` accepts `projectToken` as well as `apiKey` in `sdkOptions`, matching iOS. `apiKey` still works. +This experimental option no longer has any effect, and screenshots are captured on the main thread. `posthog-react-native` ## Native SDK 4.0: not merged yet -## Native SDK 4.0: not merged yet + - - -3.0.0 isn't meant to ship until it requires `posthog-ios` 4.0 ([#5237](https://github.com/PostHog/posthog-js/pull/5237)). Moving to `posthog-android` 4.0 is also proposed ([#5476](https://github.com/PostHog/posthog-js/pull/5476)). Both PRs are open and could change, and this branch still pins `posthog-ios` 3.92.7 and `posthog-android` 3.74.2. If they land as written: +3.0.0 isn't meant to ship until it requires `posthog-ios` 4.0 ([#5237](https://github.com/PostHog/posthog-js/pull/5237)). That PR is open and could change, and this branch still pins `posthog-ios` 3.92.7. If it lands as written: - iOS builds need Xcode 26 or later. - iOS native uploads, such as session replay and native crash reports, pause while cellular data is turned off for the app. - Apps on React Native's full Swift Package Manager integration leave out native surveys. The plugin doesn't use them, because surveys render in JavaScript. +- Native code in your app that calls `posthog-ios` directly must handle its 4.0 API removals. See the [posthog-ios migration guide](https://github.com/PostHog/posthog-ios/blob/main/MIGRATION.md). + +ipt. + - Native code in your app that calls PostHog's iOS or Android SDK directly must handle their 4.0 API removals. See the [posthog-ios migration guide](https://github.com/PostHog/posthog-ios/blob/main/MIGRATION.md). ## Checklist From 2dc831791455d938e71169dce54edaaa63821411 Mon Sep 17 00:00:00 2001 From: Anna Garcia Date: Fri, 30 Oct 2026 22:06:22 -0400 Subject: [PATCH 3/3] chore(react-native-plugin): drop posthog-android's screenshot option --- .changeset/rn-plugin-v3.md | 1 + packages/react-native-plugin/MIGRATION.md | 4 ++++ .../PosthogReactNativePluginModule.kt | 3 +-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.changeset/rn-plugin-v3.md b/.changeset/rn-plugin-v3.md index c426199635..4a3e6337bb 100644 --- a/.changeset/rn-plugin-v3.md +++ b/.changeset/rn-plugin-v3.md @@ -13,5 +13,6 @@ Release `@posthog/react-native-plugin` 3.0, with the upgrade steps in the [migra - **Breaking:** ignore `iOSdebouncerDelayMs` and `androidDebouncerDelayMs` when calling `setup()` directly — pass `throttleDelayMs` instead - **Breaking:** ignore the experimental iOS session replay option `screenshotModeBackgroundCapture` - **Breaking:** require posthog-android 4.0 +- Always record Android session replay as masked screenshots, the mode the plugin already used - Accept `projectToken` as well as `apiKey` in `setup()` options on Android - Treat the plugin's `start()` method as optional in `posthog-react-native` diff --git a/packages/react-native-plugin/MIGRATION.md b/packages/react-native-plugin/MIGRATION.md index fc80ba7b01..f800f16f73 100644 --- a/packages/react-native-plugin/MIGRATION.md +++ b/packages/react-native-plugin/MIGRATION.md @@ -103,6 +103,10 @@ sdkReplayConfig: { throttleDelayMs: 500 } **If ignored:** replay silently uses the 1000 ms default. +### Android session replay records only masked screenshots + +`posthog-android` 4.0 removes wireframe capture. The plugin already forced screenshot mode, so your recordings don't change. If native code in your app sets `sessionReplayConfig.screenshot`, remove it, because it no longer compiles. + ### `screenshotModeBackgroundCapture` is ignored on iOS This experimental option no longer has any effect, and screenshots are captured on the main thread. `posthog-react-native` ## Native SDK 4.0: not merged yet diff --git a/packages/react-native-plugin/android/src/main/java/com/posthogreactnativeplugin/PosthogReactNativePluginModule.kt b/packages/react-native-plugin/android/src/main/java/com/posthogreactnativeplugin/PosthogReactNativePluginModule.kt index d18a515d16..e525c820fc 100644 --- a/packages/react-native-plugin/android/src/main/java/com/posthogreactnativeplugin/PosthogReactNativePluginModule.kt +++ b/packages/react-native-plugin/android/src/main/java/com/posthogreactnativeplugin/PosthogReactNativePluginModule.kt @@ -158,7 +158,7 @@ class PosthogReactNativePluginModule( addBeforeSend { restoreJsFatalCaptureProperties(it) } // Always apply the session replay configuration so that recording started later - // (e.g. startRecording or a linked feature flag) uses the right mode and masking; + // (e.g. startRecording or a linked feature flag) uses the right masking; // sessionReplayEnabled only controls whether recording starts at setup. val maskAllTextInputs = getBoolean(sdkReplayConfig, "maskAllTextInputs", DEFAULT_MASK_ALL_TEXT_INPUTS) val maskAllImages = getBoolean(sdkReplayConfig, "maskAllImages", DEFAULT_MASK_ALL_IMAGES) @@ -167,7 +167,6 @@ class PosthogReactNativePluginModule( val throttleDelayMs = getInt(sdkReplayConfig, "throttleDelayMs", DEFAULT_THROTTLE_DELAY_MS) sessionReplay = sessionReplayEnabled - sessionReplayConfig.screenshot = true sessionReplayConfig.captureTouches = getBoolean(sdkReplayConfig, "captureTouches", true) sessionReplayConfig.captureLogcat = captureLog sessionReplayConfig.throttleDelayMs = throttleDelayMs.toLong()