From 5cf4a39ed10a8ddfc8489b1462410269c049ea87 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:45:52 +0500 Subject: [PATCH 01/49] docs(react-native): move the 6.x pages under v6 and mark them as the previous version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing pages keep their content; slugs and internal links move to /sdk/react_native/v6/, each page gets a 'Previous version' banner pointing at the 7.x beta, the sidebar groups them under 'Previous versions', and the docs index keeps pointing at the stable 6.x pages while 7.x is in beta. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I9b5748f3d7ac6259eb19ea581f90a7b86599b728 --- docs/index.md | 18 +-- .../react_native/{ => v6}/configuration.mdx | 6 +- docs/sdk/react_native/{ => v6}/crashes.mdx | 8 +- docs/sdk/react_native/{ => v6}/custom.md | 6 +- .../react_native/{ => v6}/errorboundary.md | 6 +- docs/sdk/react_native/{ => v6}/feedback.md | 6 +- .../sdk/react_native/{ => v6}/installation.md | 8 +- docs/sdk/react_native/{ => v6}/lifecycle.md | 6 +- docs/sdk/react_native/{ => v6}/logs.md | 6 +- docs/sdk/react_native/{ => v6}/manual.md | 6 +- docs/sdk/react_native/{ => v6}/network.md | 6 +- .../sdk/react_native/{ => v6}/privacy/logs.md | 8 +- .../react_native/{ => v6}/privacy/network.md | 8 +- .../react_native/{ => v6}/privacy/overview.md | 12 +- .../react_native/{ => v6}/privacy/video.md | 6 +- .../react_native/{ => v6}/release-notes.md | 6 +- sidebars.ts | 103 ++++++++++-------- 17 files changed, 146 insertions(+), 79 deletions(-) rename docs/sdk/react_native/{ => v6}/configuration.mdx (94%) rename docs/sdk/react_native/{ => v6}/crashes.mdx (92%) rename docs/sdk/react_native/{ => v6}/custom.md (91%) rename docs/sdk/react_native/{ => v6}/errorboundary.md (87%) rename docs/sdk/react_native/{ => v6}/feedback.md (65%) rename docs/sdk/react_native/{ => v6}/installation.md (88%) rename docs/sdk/react_native/{ => v6}/lifecycle.md (84%) rename docs/sdk/react_native/{ => v6}/logs.md (75%) rename docs/sdk/react_native/{ => v6}/manual.md (77%) rename docs/sdk/react_native/{ => v6}/network.md (70%) rename docs/sdk/react_native/{ => v6}/privacy/logs.md (74%) rename docs/sdk/react_native/{ => v6}/privacy/network.md (81%) rename docs/sdk/react_native/{ => v6}/privacy/overview.md (61%) rename docs/sdk/react_native/{ => v6}/privacy/video.md (85%) rename docs/sdk/react_native/{ => v6}/release-notes.md (97%) diff --git a/docs/index.md b/docs/index.md index 0e5843d..b1255d5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,7 +12,7 @@ Using Bugsee on mobile devices requires installation of Bugsee lightweight SDK: * [Installing iOS SDK](/sdk/ios/installation/) * [Installing Android SDK](/sdk/android/installation/) * [Installing Cordova SDK](/sdk/cordova/installation/) -* [Installing React Native SDK](/sdk/react_native/installation/) +* [Installing React Native SDK](/sdk/react_native/v6/installation/) * [Installing Flutter SDK](/sdk/flutter/installation/) * [Installing Unity SDK](/sdk/unity/installation/) * [Installing KMP SDK (Beta)](/sdk/kmp/installation/) @@ -111,7 +111,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View - View + View View @@ -133,7 +133,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View View - View + View View View View @@ -144,7 +144,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View - View + View View View View @@ -155,7 +155,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View View - View + View View View View @@ -166,7 +166,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View View - View + View View View View @@ -177,7 +177,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View View - View + View View View View @@ -188,7 +188,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View View - View + View View View View @@ -199,7 +199,7 @@ Bugsee has a very rich feature set, yet on some platforms we managed to achieve View View View - View + View View View View diff --git a/docs/sdk/react_native/configuration.mdx b/docs/sdk/react_native/v6/configuration.mdx similarity index 94% rename from docs/sdk/react_native/configuration.mdx rename to docs/sdk/react_native/v6/configuration.mdx index e9b8b58..e18f1d7 100644 --- a/docs/sdk/react_native/configuration.mdx +++ b/docs/sdk/react_native/v6/configuration.mdx @@ -2,12 +2,16 @@ title: "Configuration" description: "Complete reference of Bugsee React Native launch options for iOS and Android, including recording, crash detection, network capture, and trigger settings." sidebar_position: 1 -slug: "/sdk/react_native/configuration" +slug: "/sdk/react_native/v6/configuration" --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + ## Launching with options :::warning diff --git a/docs/sdk/react_native/crashes.mdx b/docs/sdk/react_native/v6/crashes.mdx similarity index 92% rename from docs/sdk/react_native/crashes.mdx rename to docs/sdk/react_native/v6/crashes.mdx index f63b2e6..a5b5b6a 100644 --- a/docs/sdk/react_native/crashes.mdx +++ b/docs/sdk/react_native/v6/crashes.mdx @@ -2,13 +2,17 @@ title: "Crash reports" description: "How to configure automatic source map uploads and symbolication for readable JavaScript and native crash stack traces in React Native." sidebar_position: 9 -slug: "/sdk/react_native/crashes" +slug: "/sdk/react_native/v6/crashes" --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Bugsee automatically intercepts uncaught exceptions and sends crash reports on app restart. Refer to [installation](/sdk/react_native/installation/) for more details. However, due to various optimizations, stack traces in these reports can be mangled. To make them human readable and point to correct code locations Bugsee requires additional debug information which should be collected and sent as described in this section. +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + +Bugsee automatically intercepts uncaught exceptions and sends crash reports on app restart. Refer to [installation](/sdk/react_native/v6/installation/) for more details. However, due to various optimizations, stack traces in these reports can be mangled. To make them human readable and point to correct code locations Bugsee requires additional debug information which should be collected and sent as described in this section. ## Symbolication diff --git a/docs/sdk/react_native/custom.md b/docs/sdk/react_native/v6/custom.md similarity index 91% rename from docs/sdk/react_native/custom.md rename to docs/sdk/react_native/v6/custom.md index 062ba00..410e62b 100644 --- a/docs/sdk/react_native/custom.md +++ b/docs/sdk/react_native/v6/custom.md @@ -2,9 +2,13 @@ title: "Adding custom data" description: "Attach user email, custom events, traces, session attributes, and file attachments to Bugsee reports in React Native." sidebar_position: 3 -slug: "/sdk/react_native/custom" +slug: "/sdk/react_native/v6/custom" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + When you already have your users identified within your app, you might want to automatically attach their email to the bug report. Bugsee provides APIs for setting, getting, and clearing the email. ```javascript diff --git a/docs/sdk/react_native/errorboundary.md b/docs/sdk/react_native/v6/errorboundary.md similarity index 87% rename from docs/sdk/react_native/errorboundary.md rename to docs/sdk/react_native/v6/errorboundary.md index c02154b..24f77d1 100644 --- a/docs/sdk/react_native/errorboundary.md +++ b/docs/sdk/react_native/v6/errorboundary.md @@ -2,9 +2,13 @@ title: "React Error Boundary" description: "Use Bugsee's ErrorBoundary component to automatically catch and report JavaScript errors thrown inside a React component tree." sidebar_position: 10 -slug: "/sdk/react_native/errorboundary" +slug: "/sdk/react_native/v6/errorboundary" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + The Bugsee React Native SDK exports an error boundary component that provides [React component APIs](https://reactjs.org/docs/error-boundaries.html) to automatically catch and send JavaScript errors from inside a React component tree to Bugsee diff --git a/docs/sdk/react_native/feedback.md b/docs/sdk/react_native/v6/feedback.md similarity index 65% rename from docs/sdk/react_native/feedback.md rename to docs/sdk/react_native/v6/feedback.md index 517caa3..4384ec0 100644 --- a/docs/sdk/react_native/feedback.md +++ b/docs/sdk/react_native/v6/feedback.md @@ -2,9 +2,13 @@ title: "Feedback" description: "Enable in-app user-to-support messaging in React Native by launching Bugsee's built-in feedback UI and configuring a default greeting." sidebar_position: 6 -slug: "/sdk/react_native/feedback" +slug: "/sdk/react_native/v6/feedback" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + Bugsee implements a built-in single-threaded messenger to allow your users to communicate with your support and developers. ## Feedback activity diff --git a/docs/sdk/react_native/installation.md b/docs/sdk/react_native/v6/installation.md similarity index 88% rename from docs/sdk/react_native/installation.md rename to docs/sdk/react_native/v6/installation.md index 906193d..8f9b716 100644 --- a/docs/sdk/react_native/installation.md +++ b/docs/sdk/react_native/v6/installation.md @@ -2,9 +2,13 @@ title: "React Native" description: "Step-by-step guide to install the react-native-bugsee module and launch Bugsee from JavaScript or native code on iOS and Android." sidebar_position: 0 -slug: "/sdk/react_native/installation" +slug: "/sdk/react_native/v6/installation" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + :::info[Agent-Assisted Setup] Ask your AI coding assistant: @@ -44,7 +48,7 @@ cd .. Download the latest version from [here](https://download.bugsee.com/sdk/ios/dynamic/Bugsee-stable.xcframework.zip) and extract it. Copy ```Bugsee.xcframework``` to your project by drag and dropping it into the right location. When asked, choose to copy: -![Copy frameworks](../ios/copy-frameworks.png) +![Copy frameworks](../../ios/copy-frameworks.png) You can also use the instructions for native iOS applications from [here](/sdk/ios/installation/) to install the native part of the Bugsee SDK for React Native. diff --git a/docs/sdk/react_native/lifecycle.md b/docs/sdk/react_native/v6/lifecycle.md similarity index 84% rename from docs/sdk/react_native/lifecycle.md rename to docs/sdk/react_native/v6/lifecycle.md index 63756f5..6698e69 100644 --- a/docs/sdk/react_native/lifecycle.md +++ b/docs/sdk/react_native/v6/lifecycle.md @@ -2,9 +2,13 @@ title: "Lifecycle events" description: "Subscribe to Bugsee SDK lifecycle events in React Native to be notified when the SDK starts, stops, pauses, or uploads reports." sidebar_position: 8 -slug: "/sdk/react_native/lifecycle" +slug: "/sdk/react_native/v6/lifecycle" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + Bugsee SDK silently works within your app, recording everything to assist you in debugging when something unexpected happens. Our SDK is designed as a black box, but there may be cases when you want to be notified about changes/events within Bugsee itself. Lifecycle events are designed exactly for that. Whenever internal state changes or some important event is raised, a lifecycle event is dispatched to the user code. ## Implementing callback diff --git a/docs/sdk/react_native/logs.md b/docs/sdk/react_native/v6/logs.md similarity index 75% rename from docs/sdk/react_native/logs.md rename to docs/sdk/react_native/v6/logs.md index cb7e48a..5807207 100644 --- a/docs/sdk/react_native/logs.md +++ b/docs/sdk/react_native/v6/logs.md @@ -2,9 +2,13 @@ title: "Logging" description: "Integrate Bugsee with the React Native logging system and send custom log messages with explicit log levels from JavaScript." sidebar_position: 4 -slug: "/sdk/react_native/logs" +slug: "/sdk/react_native/v6/logs" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + Bugsee provides a way to hook Bugsee as custom logger to React Native logging system. With this, console.log(), console.warn(), console.error() as well as React Native internal logs will be properly handled by Bugsee. diff --git a/docs/sdk/react_native/manual.md b/docs/sdk/react_native/v6/manual.md similarity index 77% rename from docs/sdk/react_native/manual.md rename to docs/sdk/react_native/v6/manual.md index 27279e4..e2db4ae 100644 --- a/docs/sdk/react_native/manual.md +++ b/docs/sdk/react_native/v6/manual.md @@ -2,9 +2,13 @@ title: "Manual invocation" description: "Programmatically trigger the bug report dialog, silently upload reports, and log non-fatal exceptions from React Native code." sidebar_position: 2 -slug: "/sdk/react_native/manual" +slug: "/sdk/react_native/v6/manual" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + ## Trigger Report view In addition to detection of a shake gesture or screenshot issue report view can be triggered programmatically from within diff --git a/docs/sdk/react_native/network.md b/docs/sdk/react_native/v6/network.md similarity index 70% rename from docs/sdk/react_native/network.md rename to docs/sdk/react_native/v6/network.md index c37b9b6..de277a8 100644 --- a/docs/sdk/react_native/network.md +++ b/docs/sdk/react_native/v6/network.md @@ -2,9 +2,13 @@ title: "Network capture" description: "Enable Bugsee network traffic capture in React Native, including the required Android OkHttp client factory setup." sidebar_position: 7 -slug: "/sdk/react_native/network" +slug: "/sdk/react_native/v6/network" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + On both Android and iOS Bugsee is capable of capturing network events made either by your JS or platform code. On iOS we automatically install required hooks and no actions should be taken from user space. However, on Android, a single line should be added to the application bootstrap flow to let us intercept network events. **Android** diff --git a/docs/sdk/react_native/privacy/logs.md b/docs/sdk/react_native/v6/privacy/logs.md similarity index 74% rename from docs/sdk/react_native/privacy/logs.md rename to docs/sdk/react_native/v6/privacy/logs.md index b04cfdc..af563f0 100644 --- a/docs/sdk/react_native/privacy/logs.md +++ b/docs/sdk/react_native/v6/privacy/logs.md @@ -2,12 +2,16 @@ title: "Privacy and console logs" description: "Disable or sanitize console log collection in React Native to prevent personally identifiable data from being included in Bugsee reports." sidebar_position: 3 -slug: "/sdk/react_native/privacy/logs" +slug: "/sdk/react_native/v6/privacy/logs" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + ## Disabling log collection -Console log collection can be disabled completely by providing corresponding launch flags. Refer to [configuration](/sdk/react_native/configuration/) and look for **captureLogs** launch option for more info. +Console log collection can be disabled completely by providing corresponding launch flags. Refer to [configuration](/sdk/react_native/v6/configuration/) and look for **captureLogs** launch option for more info. ## Sanitizing console logs diff --git a/docs/sdk/react_native/privacy/network.md b/docs/sdk/react_native/v6/privacy/network.md similarity index 81% rename from docs/sdk/react_native/privacy/network.md rename to docs/sdk/react_native/v6/privacy/network.md index f26fa43..d69efcf 100644 --- a/docs/sdk/react_native/privacy/network.md +++ b/docs/sdk/react_native/v6/privacy/network.md @@ -2,12 +2,16 @@ title: "Privacy and Network traffic" description: "Disable or filter captured network requests and responses in React Native to strip sensitive data before it is recorded by Bugsee." sidebar_position: 2 -slug: "/sdk/react_native/privacy/network" +slug: "/sdk/react_native/v6/privacy/network" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + ## Disabling network traffic collection -Network traffic collection can be disabled completely by providing corresponding launch flags. Refer to [configuration](/sdk/react_native/configuration/) and look for **monitorNetwork** launch option for more info. +Network traffic collection can be disabled completely by providing corresponding launch flags. Refer to [configuration](/sdk/react_native/v6/configuration/) and look for **monitorNetwork** launch option for more info. ## Sanitizing data diff --git a/docs/sdk/react_native/privacy/overview.md b/docs/sdk/react_native/v6/privacy/overview.md similarity index 61% rename from docs/sdk/react_native/privacy/overview.md rename to docs/sdk/react_native/v6/privacy/overview.md index 9163397..a85d869 100644 --- a/docs/sdk/react_native/privacy/overview.md +++ b/docs/sdk/react_native/v6/privacy/overview.md @@ -2,9 +2,13 @@ title: "Privacy overview" description: "Overview of privacy considerations for Bugsee in React Native and the tools available to prevent or sanitize PII in reports." sidebar_position: 0 -slug: "/sdk/react_native/privacy/overview" +slug: "/sdk/react_native/v6/privacy/overview" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + Bugsee SDK does not continuously stream any personal data. The reports are stored locally on the phone in a cyclical buffer. Reports are being sent only when triggered by a crash, through a bug reporting UI or from an application's code. Data sent along with the reports may include video recording of screen, network and console logs. These may potentially contain PII (Personally Identifiable Information). @@ -12,9 +16,9 @@ It is the sole responsibility of the application developers to remove any such d Bugsee provides the tools and means to either prevent some data from being collected or clean the data during the collection process: -* [Video and Touch](/sdk/react_native/privacy/video/) -* [Network](/sdk/react_native/privacy/network/) -* [Console logs](/sdk/react_native/privacy/logs/) +* [Video and Touch](/sdk/react_native/v6/privacy/video/) +* [Network](/sdk/react_native/v6/privacy/network/) +* [Console logs](/sdk/react_native/v6/privacy/logs/) diff --git a/docs/sdk/react_native/privacy/video.md b/docs/sdk/react_native/v6/privacy/video.md similarity index 85% rename from docs/sdk/react_native/privacy/video.md rename to docs/sdk/react_native/v6/privacy/video.md index 43d04a3..ec22763 100644 --- a/docs/sdk/react_native/privacy/video.md +++ b/docs/sdk/react_native/v6/privacy/video.md @@ -2,9 +2,13 @@ title: "Privacy and video" description: "Pause screen recording, mark UI components as protected, and define secure rectangles to hide sensitive content from Bugsee video in React Native." sidebar_position: 1 -slug: "/sdk/react_native/privacy/video" +slug: "/sdk/react_native/v6/privacy/video" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + # Going dark In some rare cases you might want to conceal the whole screen and stop recording events completely. The following APIs will come in handy, no data is being gathered between the calls to pause and resume. diff --git a/docs/sdk/react_native/release-notes.md b/docs/sdk/react_native/v6/release-notes.md similarity index 97% rename from docs/sdk/react_native/release-notes.md rename to docs/sdk/react_native/v6/release-notes.md index 2533006..7b9b908 100644 --- a/docs/sdk/react_native/release-notes.md +++ b/docs/sdk/react_native/v6/release-notes.md @@ -2,9 +2,13 @@ title: "Release notes" description: "Changelog for the Bugsee React Native SDK listing new features, bug fixes, and breaking changes for each released version." sidebar_position: 11 -slug: "/sdk/react_native/release-notes" +slug: "/sdk/react_native/v6/release-notes" --- +:::caution[Previous version] +This page documents Bugsee React Native SDK **6.x** (`react-native-bugsee`), the current stable release. The new **7.x** SDK (`@bugsee/react-native`) is in beta: see [Migrating from 6.x to 7.x](/sdk/react_native/migration) to evaluate it, or the [7.x overview](/sdk/react_native/overview) to start a new integration. +::: + ## 6.0.5 (August 18 2026) - Internal improvements. diff --git a/sidebars.ts b/sidebars.ts index 7340430..c2af301 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -546,72 +546,79 @@ const sidebars: SidebarsConfig = { label: "React Native SDK", collapsed: true, items: [ - { - type: "doc", - id: "sdk/react_native/installation", - label: "Installation", - }, - { - type: "doc", - id: "sdk/react_native/configuration", - label: "Configuration", - }, - { - type: "doc", - id: "sdk/react_native/manual", - label: "Manual invocation", - }, - { type: "doc", id: "sdk/react_native/custom", label: "Custom data" }, - { type: "doc", id: "sdk/react_native/logs", label: "Console logs" }, { type: "category", - label: "Privacy", + label: "Previous versions", collapsed: true, items: [ { type: "doc", - id: "sdk/react_native/privacy/overview", - label: "Overview", + id: "sdk/react_native/v6/installation", + label: "Installation", }, { type: "doc", - id: "sdk/react_native/privacy/video", - label: "Video", + id: "sdk/react_native/v6/configuration", + label: "Configuration", }, { type: "doc", - id: "sdk/react_native/privacy/network", - label: "Network", + id: "sdk/react_native/v6/manual", + label: "Manual invocation", + }, + { type: "doc", id: "sdk/react_native/v6/custom", label: "Custom data" }, + { type: "doc", id: "sdk/react_native/v6/logs", label: "Console logs" }, + { + type: "category", + label: "Privacy", + collapsed: true, + items: [ + { + type: "doc", + id: "sdk/react_native/v6/privacy/overview", + label: "Overview", + }, + { + type: "doc", + id: "sdk/react_native/v6/privacy/video", + label: "Video", + }, + { + type: "doc", + id: "sdk/react_native/v6/privacy/network", + label: "Network", + }, + { + type: "doc", + id: "sdk/react_native/v6/privacy/logs", + label: "Console logs", + }, + ], }, + { type: "doc", id: "sdk/react_native/v6/feedback", label: "Feedback" }, { type: "doc", - id: "sdk/react_native/privacy/logs", - label: "Console logs", + id: "sdk/react_native/v6/network", + label: "Network capture", + }, + { + type: "doc", + id: "sdk/react_native/v6/lifecycle", + label: "Lifecycle events", + }, + { type: "doc", id: "sdk/react_native/v6/crashes", label: "Crash reports" }, + { + type: "doc", + id: "sdk/react_native/v6/errorboundary", + label: "Error boundary", + }, + { + type: "doc", + id: "sdk/react_native/v6/release-notes", + label: "Release notes", }, ], }, - { type: "doc", id: "sdk/react_native/feedback", label: "Feedback" }, - { - type: "doc", - id: "sdk/react_native/network", - label: "Network capture", - }, - { - type: "doc", - id: "sdk/react_native/lifecycle", - label: "Lifecycle events", - }, - { type: "doc", id: "sdk/react_native/crashes", label: "Crash reports" }, - { - type: "doc", - id: "sdk/react_native/errorboundary", - label: "Error boundary", - }, - { - type: "doc", - id: "sdk/react_native/release-notes", - label: "Release notes", - }, ], }, { From 18bd5ad347c8317592641bd187324848f89e8342 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:45:52 +0500 Subject: [PATCH 02/49] docs(react-native): sidebar link to the stable 6.x documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Iad05dc2d1a11da69c9fbe857ed9bedd9461fe7f8 --- sidebars.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sidebars.ts b/sidebars.ts index c2af301..544e7bd 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -546,6 +546,11 @@ const sidebars: SidebarsConfig = { label: "React Native SDK", collapsed: true, items: [ + { + type: "link", + label: "Stable release (6.x) docs", + href: "/sdk/react_native/v6/installation", + }, { type: "category", label: "Previous versions", From 0572c54390beff679f55804c7625257bef8d0958 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:50:53 +0500 Subject: [PATCH 03/49] docs(react-native): Overview (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What the React Native SDK 7.x records and detects, how it wraps the native SDKs, requirements and the native SDK versions it is built on. Verified against packages/react-native/README.md, src/index.ts, native-versions.json and android/build.gradle in bugsee-react-native. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ie240101b28822710b59afc3eea680ac80796aad2 --- cspell.json | 3 +- docs/sdk/react_native/overview.mdx | 80 ++++++++++++++++++++++++++++++ sidebars.ts | 5 ++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/react_native/overview.mdx diff --git a/cspell.json b/cspell.json index 678585f..c75a2ed 100644 --- a/cspell.json +++ b/cspell.json @@ -231,6 +231,7 @@ "sandboxing", "libil", "unbreak", - "Podspec" + "Podspec", + "javascriptcore" ] } \ No newline at end of file diff --git a/docs/sdk/react_native/overview.mdx b/docs/sdk/react_native/overview.mdx new file mode 100644 index 0000000..8c62830 --- /dev/null +++ b/docs/sdk/react_native/overview.mdx @@ -0,0 +1,80 @@ +--- +title: "Overview" +description: "What the Bugsee React Native SDK 7.x records and detects, how it wraps the native iOS and Android SDKs, and what your app needs to run it." +sidebar_position: 0 +slug: "/sdk/react_native/overview" +--- + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +The Bugsee React Native SDK (`@bugsee/react-native`) captures what happened before a bug: a video of the screen, network traffic, console logs and the steps that led to it. It attaches that timeline to crash, error and bug reports you can replay in the Bugsee dashboard. + +The package is built on the native Bugsee SDKs for Android and iOS, and gives both platforms one JavaScript API: a report from a React Native app is the same report a native app produces, with the JavaScript layer added. + +## What Bugsee records + +Every report carries a synchronized timeline of the session that led up to it: + +- **Video**: a rolling recording of the screen. Wrap anything that must never be recorded in ``; see [Privacy: Video](/sdk/react_native/privacy/video). +- **Network**: requests your app makes through `fetch` and `XMLHttpRequest` travel through the platform's networking stack, where the SDK records them (on Android, only with the Bugsee Gradle plugin applied; see [Installation](/sdk/react_native/installation#android)). You can add events from other stacks yourself and filter what is recorded; see [Network events](/sdk/react_native/network). +- **Console logs**: `console.error`, `warn`, `log`, `info` and `debug` are forwarded to Bugsee and still print as before; see [Console logs](/sdk/react_native/logs). +- **Breadcrumbs**: system events recorded automatically (such as app lifecycle changes), plus breadcrumbs you add. The package records no automatic touch or navigation breadcrumbs for React components. Off until you turn them on; see [Breadcrumbs](/sdk/react_native/breadcrumbs). +- **Custom events, traces and attributes**: see [Custom events & traces](/sdk/react_native/events-and-traces) and [User & session data](/sdk/react_native/user-session-data). +- **Performance (APM)**: [transactions and spans](/sdk/react_native/performance) you start from JavaScript. + +## What Bugsee detects + +The SDK turns problems into reports automatically: + +- **JavaScript exceptions**: `Bugsee.launch()` installs global handlers for uncaught errors and unhandled promise rejections. An [error boundary](/sdk/react_native/error-boundary) reports render errors. +- **Native crashes**: on Android, uncaught Java and Kotlin exceptions and native (NDK) crashes; on iOS, uncaught Objective-C exceptions and fatal signals, including Swift runtime traps. See [Native crashes](/sdk/react_native/manual/crash-error-reporting#native-crashes). +- **Handled errors** you report yourself; see [Crash & error reporting](/sdk/react_native/manual/crash-error-reporting). +- **Manual reports**: let users shake the device to report, or open the report dialog or upload a report from code; see [Bug reporting](/sdk/react_native/manual/bug-reporting). + +## How it works + +- **One package.** `@bugsee/react-native` brings the native SDKs with it: autolinking adds the Android module, and the iOS SDK comes through the package's `Package.swift` when your app uses React Native's Swift Package Manager integration (0.87 and later), or through the package's podspec with CocoaPods. You don't add the native SDKs yourself: no Podfile pod, no Maven dependency. +- **Launch from JavaScript.** One call, `Bugsee.launch(token, options)`, starts the SDK; see [Installation](/sdk/react_native/installation) and [Lifecycle & status](/sdk/react_native/lifecycle). +- **One option namespace.** The same `com.bugsee.option.*` keys work on both platforms, so one options object configures both; see [Configuration](/sdk/react_native/configuration). +- **Privacy on the device.** Mask views with ``, and filter or drop network, log and breadcrumb data before it is recorded; see [Privacy](/sdk/react_native/privacy/overview). +- **Readable release reports.** Release builds can upload JavaScript source maps, Android mapping and native symbols, and iOS dSYMs, so crash frames resolve to your source. An Expo app gets this from the [config plugin](/sdk/react_native/expo); a bare app adds a few build steps; see [Symbolication](/sdk/react_native/symbolication/overview). +- **Automatic upload.** Reports upload to the dashboard in the background. + +The in-app feedback chat ships separately, as `@bugsee/react-native-feedback`, so apps that never show it do not depend on it; see [Feedback](/sdk/react_native/feedback). + +## Requirements + +| | | +| --- | --- | +| React Native | 0.81 or later, with the New Architecture enabled | +| JavaScript engine | Hermes (React Native's default) | +| iOS | 15.0 or later | +| Android | API 21 or later | + +The New Architecture is the default from React Native 0.76. On 0.81 it can still be turned off; this package requires it on. + +Hermes is required. JavaScriptCore (Hermes off) is not supported: React Native removed JSC from core in 0.81, and the community package that replaces it, `@react-native-community/javascriptcore`, does not work with current React Native. + +## Versions + +This beta, `7.0.0-beta2`, is built on these native SDKs: + +| Platform | Native SDK | Notes | +| --- | --- | --- | +| Android | `com.bugsee:bugsee-android` 7.4.2 | Bugsee Gradle plugin 4.0.8 for release uploads and Android network capture | +| iOS | Bugsee iOS SDK 7.0.0-beta7 | The iOS SDK is itself a beta | + +`@bugsee/react-native` 7.x replaces `react-native-bugsee` 6.x. They are different packages with different APIs, not an upgrade in place: remove the old package and follow [Migrating from 6.x to 7.x](/sdk/react_native/migration). + +## Get started + +Head to [Installation](/sdk/react_native/installation) for a React Native CLI app, or [Expo](/sdk/react_native/expo) if you use Expo prebuild. From there, [Configuration](/sdk/react_native/configuration) covers the launch options, and [Privacy](/sdk/react_native/privacy/overview) covers redaction. + +## Related pages + +- [Installation](/sdk/react_native/installation): add the package and launch the SDK. +- [Expo](/sdk/react_native/expo): the config plugin for Expo prebuild. +- [Configuration](/sdk/react_native/configuration): launch options for both platforms. +- [Lifecycle & status](/sdk/react_native/lifecycle): launch, stop, relaunch and querying status. diff --git a/sidebars.ts b/sidebars.ts index 544e7bd..57d605d 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -551,6 +551,11 @@ const sidebars: SidebarsConfig = { label: "Stable release (6.x) docs", href: "/sdk/react_native/v6/installation", }, + { + type: "doc", + id: "sdk/react_native/overview", + label: "Overview", + }, { type: "category", label: "Previous versions", From 9686a20a438939ffc79bf81b2d3c55833180e67e Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:51:49 +0500 Subject: [PATCH 04/49] docs(react-native): Installation (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit React Native CLI install: requirements, the @beta package, iOS (SPM on 0.87+, vendored podspec before), Android autolinking and what still needs the Gradle plugin, pnpm notes, app tokens, Bugsee.launch and verification. Verified against packages/react-native/README.md, src/index.ts, BugseeReactNative.podspec, android/build.gradle and the native BugseeModule launch paths. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I235748e1338bb26f92f25038b23dfa850e36f853 --- docs/sdk/react_native/installation.mdx | 201 +++++++++++++++++++++++++ sidebars.ts | 12 ++ 2 files changed, 213 insertions(+) create mode 100644 docs/sdk/react_native/installation.mdx diff --git a/docs/sdk/react_native/installation.mdx b/docs/sdk/react_native/installation.mdx new file mode 100644 index 0000000..e0688ab --- /dev/null +++ b/docs/sdk/react_native/installation.mdx @@ -0,0 +1,201 @@ +--- +title: "Installation" +description: "Installing Bugsee React Native SDK 7.x in a React Native CLI (bare) app, launching it from JavaScript, and checking that reports arrive." +sidebar_position: 1 +slug: "/sdk/react_native/installation" +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +This page covers a React Native CLI (bare) app, where you own the `ios/` and `android/` projects. If your app uses Expo prebuild, add the package as shown here, then follow [Expo](/sdk/react_native/expo) for the native setup. + +:::caution[Replacing 6.x] +`@bugsee/react-native` replaces `react-native-bugsee` (6.x). They are different packages with different APIs, not an upgrade in place. Remove `react-native-bugsee` first; [Migrating from 6.x to 7.x](/sdk/react_native/migration) lists the API changes. +::: + +## Requirements + +| | | +| --- | --- | +| React Native | 0.81 or later, with the New Architecture enabled | +| JavaScript engine | Hermes (React Native's default) | +| iOS | 15.0 or later (see the note below) | +| Android | API 21 or later | + +The New Architecture is the default from React Native 0.76. On 0.81 it can still be turned off; this package requires it on. Hermes is required: JavaScriptCore is not supported. + +The Bugsee iOS SDK itself supports iOS 15.0. With CocoaPods, the podspec takes React Native's own minimum, which is 15.1, so that is the effective floor there. + +## 1. Add the package + + + + +```sh +yarn add @bugsee/react-native@beta +``` + + + + +```sh +npm install @bugsee/react-native@beta +``` + + + + +```sh +pnpm add @bugsee/react-native@beta +``` + + + + +For now the npm `latest` and `beta` tags both point at this beta, so a plain `yarn add @bugsee/react-native` installs it too. The `@beta` form keeps following betas once a stable 7.x release exists. + +### pnpm + +React Native needs `nodeLinker: hoisted` under pnpm. + +pnpm 10 and later run no dependency's install script unless the project decides, and pnpm 11 fails the install until it does (`ERR_PNPM_IGNORED_BUILDS`). The package depends on `@bugsee/cli`, which uploads symbols and source maps and has a `postinstall` script. Its binary comes from a platform-specific optional dependency, so the script is only a download fallback for registry mirrors that lack those packages. Decide in `pnpm-workspace.yaml`: + +```yaml title="pnpm-workspace.yaml" +allowBuilds: + '@bugsee/cli': false # true only if your registry lacks @bugsee/cli- +``` + +## 2. Native setup + +### iOS + +If your app uses React Native's Swift Package Manager integration (React Native 0.87 and later), the package's own `Package.swift` provides the SDK. React Native's autolinking references that package directly; there is no Bugsee-specific step to run. + +Otherwise (CocoaPods, on any React Native version) the package's podspec downloads the same XCFramework from `download.bugsee.com` during `pod install` and vendors it, so install pods as usual: + +```sh +cd ios && pod install +``` + +Nothing is published to CocoaPods trunk, so you don't need `pod repo update`. + +For readable iOS crash reports in Release, a bare app also needs two build edits: point the **Bundle React Native code and images** build phase at the package's `bugsee-xcode.sh` (which uploads the JavaScript source map, with a token from `BUGSEE_APP_TOKEN` in, for example, `ios/.xcode.env.local`), and add the dSYM upload post-action to the scheme's Archive action. Both are described in [Symbolication: iOS](/sdk/react_native/symbolication/ios). Without them the app still builds and runs, but JavaScript and native frames in Release reports stay unsymbolicated. + +### Android + +Autolinking picks up the module. The app builds and launches with no Gradle changes. + +The package brings in the Android SDK together with its NDK crash reporting and OkHttp modules. Three things still need edits that autolinking cannot make: + +- **JavaScript source maps**: two edits in `android/app/build.gradle`, pointing `react.hermesCommand` at the package's Hermes wrapper and applying the package's `scripts/bugsee-sourcemaps.gradle`, which gives the bundle a debug id and uploads its map with `@bugsee/cli`. These do not need the Gradle plugin. +- **R8/ProGuard mapping and native symbols**: uploaded by the **Bugsee Gradle plugin** (`com.bugsee.android.gradle`). +- **Network capture of `fetch` and `XMLHttpRequest`**: React Native sends these through OkHttp, and the Bugsee Gradle plugin is what lets the SDK record OkHttp traffic. **Without the plugin, these requests are not recorded on Android.** + +All of these edits are listed in [Symbolication: Android](/sdk/react_native/symbolication/android). Without them the app still builds and runs, but Android reports carry no `fetch`/XHR network events, and JavaScript and native frames in Release reports stay unsymbolicated. + +## 3. Get your app tokens + +Bugsee app tokens are per platform: your iOS app and your Android app each have their own token in the Bugsee dashboard. Pick the right one at runtime from `Platform.OS`, as in the next step. + +## 4. Launch Bugsee + +Call `Bugsee.launch` once, as early as you can. The top of `index.js` is a good place: `` follows native animation events only from the moment `@bugsee/react-native` is first evaluated, so importing it there masks correctly from the start. + +```ts title="index.js" +import { AppRegistry, Platform } from 'react-native'; +import Bugsee, { createDefaultLaunchOptions } from '@bugsee/react-native'; +import App from './App'; +import { name as appName } from './app.json'; + +const token = + Platform.OS === 'ios' ? '' : ''; + +const options = createDefaultLaunchOptions(); +options.captureLogs = true; + +Bugsee.launch(token, options); + +// Bugsee.wrap captures the view hierarchy and reports uncaught render errors. +AppRegistry.registerComponent(appName, () => Bugsee.wrap(App)); +``` + +What this does: + +- **`createDefaultLaunchOptions()`** returns an empty options object for the running platform. It is not pre-filled: every option you leave unset keeps the native SDK's own default. See [Configuration](/sdk/react_native/configuration) for every option. +- **`Bugsee.launch(token, options)`** takes the options object as is; there is no serialize step to call. It also accepts a plain map of `com.bugsee.option.*` keys, for options you build or merge yourself: + + ```ts + Bugsee.launch(token, { + 'com.bugsee.option.capture.logs': true, + 'com.bugsee.option.config.duration': 60, + }); + ``` + +- **`Bugsee.wrap(App)`** renders your root component unchanged, next to an invisible anchor the SDK uses to find the view tree, inside a reporter for uncaught render errors. Without it, reports carry no view hierarchy, and an uncaught render error is not reported (render errors do not reach the global error handler); see [Render errors](/sdk/react_native/manual/crash-error-reporting#render-errors). + +`launch` also installs the JavaScript exception handlers (uncaught errors and unhandled promise rejections) and, once the native SDK has answered, forwards `console.*` output to Bugsee. + +### What `launch` resolves to + +`launch` resolves to `true` when the SDK started, and `false` when it declined, for example because the backend rejected the token. Declining is not an error, so `launch` does not reject for it. A `launch` while the SDK is already running also resolves `true`, but its options are not applied; see [Launching again](/sdk/react_native/lifecycle#launching-again). + +A missing, empty or blank token is rejected before the SDK is launched, with an error whose `code` is `E_TOKEN`. + +Capture comes up asynchronously on both platforms, so a resolved `launch` does not mean recording has begun. Poll `Bugsee.getStatus()` or subscribe with `Bugsee.onStatusChange` when you need to know; see [Lifecycle & status](/sdk/react_native/lifecycle). + +:::tip[Register handlers before launch] +If you use a [report handler](/sdk/react_native/report-handler), call `Bugsee.setReportHandler` **before** `Bugsee.launch`. A handler installed afterward misses the reports that launch recovers, such as a crash from the previous run. +::: + +## 5. Verify + +Build and run the app, then send a test report: + +1. Check that the SDK is running (capture comes up shortly after `launch` resolves, so check a moment later, or use `Bugsee.onStatusChange`): + + ```ts + import Bugsee, { Status } from '@bugsee/react-native'; + + async function checkBugsee() { + const status = await Bugsee.getStatus(); + console.log(status === Status.Launched ? 'Bugsee is running' : `Bugsee status: ${status}`); + } + ``` + +2. Open the report dialog with `Bugsee.showReportDialog()`, fill it in and send it. To check crash reporting instead, call `Bugsee.testJsCrash()`, which throws a JavaScript error at the call site (in a development build, React Native also shows its error screen), or `Bugsee.testNativeCrash()`, which raises the native SDK's own test crash (a Java `RuntimeException` on Android, an `NSException` on iOS). +3. Open your app in the Bugsee dashboard and find the report, with its video, logs and network events. On Android, `fetch`/XHR network events appear only with the Bugsee Gradle plugin applied; see [Android](#android). + +:::note +`showReportDialog` and `upload` do nothing before `launch()`. If no report arrives, check that `launch` resolved `true` and that you used the token of the platform you are running. +::: + +## Troubleshooting + +### iOS build fails in `fmt` + +{/* cspell:ignore consteval fmtlib */} + +On React Native 0.81 and 0.82 with Xcode 26.4 or later, the iOS build can fail in the `fmt` pod with "call to consteval function … is not a constant expression". This is not caused by Bugsee: those React Native versions build `fmt` 11.0.2 from source, which newer Apple clang rejects as C++20 ([fmtlib/fmt#4740](https://github.com/fmtlib/fmt/issues/4740)). React Native 0.83 and later ship `fmt` 12 and are not affected. + +Build that one pod as C++17 from the `post_install` block of `ios/Podfile`, after `react_native_post_install(...)`, then run `pod install` again: + +```ruby title="ios/Podfile" + installer.pods_project.targets.each do |target| + next unless target.name == 'fmt' + target.build_configurations.each do |config| + config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++17' + end + end +``` + +## Next steps + +- [Configuration](/sdk/react_native/configuration): launch options for both platforms. +- [Lifecycle & status](/sdk/react_native/lifecycle): stop, relaunch and the lifecycle events. +- [Symbolication](/sdk/react_native/symbolication/overview): readable stack traces in Release builds. +- [Privacy](/sdk/react_native/privacy/overview): mask views and filter captured data. diff --git a/sidebars.ts b/sidebars.ts index 57d605d..fee8551 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -556,6 +556,18 @@ const sidebars: SidebarsConfig = { id: "sdk/react_native/overview", label: "Overview", }, + { + type: "category", + label: "Installation & Invocation", + collapsed: true, + items: [ + { + type: "doc", + id: "sdk/react_native/installation", + label: "Installation", + }, + ], + }, { type: "category", label: "Previous versions", From 9b8874f04ce71e23a5f9c70bbdf96eae81724d11 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:53:22 +0500 Subject: [PATCH 05/49] docs(react-native): Expo (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Expo config plugin: the plugins entry, every option with its default, what expo prebuild writes on Android and iOS, Android auto-launch with attach(), the endpoint option, React Native dSYMs and the edits the plugin refuses. Verified against packages/react-native/plugin/src/* and the README "Expo config plugin". 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I1bdd2e5924c2b5423cf7f05da2de111167d19f1f --- cspell.json | 4 +- docs/sdk/react_native/expo.mdx | 201 +++++++++++++++++++++++++++++++++ sidebars.ts | 5 + 3 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/react_native/expo.mdx diff --git a/cspell.json b/cspell.json index c75a2ed..5363f31 100644 --- a/cspell.json +++ b/cspell.json @@ -232,6 +232,8 @@ "libil", "unbreak", "Podspec", - "javascriptcore" + "javascriptcore", + "reactnative", + "slashy" ] } \ No newline at end of file diff --git a/docs/sdk/react_native/expo.mdx b/docs/sdk/react_native/expo.mdx new file mode 100644 index 0000000..422a02d --- /dev/null +++ b/docs/sdk/react_native/expo.mdx @@ -0,0 +1,201 @@ +--- +title: "Expo" +description: "Setting up Bugsee React Native SDK 7.x in an Expo app with the config plugin: its options, what it writes on expo prebuild, and its limits." +sidebar_position: 2 +slug: "/sdk/react_native/expo" +--- + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +Expo apps regenerate `ios/` and `android/` on every `expo prebuild`, so native edits made by hand do not survive. `@bugsee/react-native` ships an Expo config plugin that makes the Bugsee build edits for you on each prebuild: the Bugsee Gradle plugin, the Hermes debug-id hooks, the source-map uploads and the iOS dSYM upload on Archive. + +The config plugin covers the **build**. Your app still starts the SDK from JavaScript with `Bugsee.launch`, as on [Installation](/sdk/react_native/installation#4-launch-bugsee). + +## Requirements + +The same as for any `@bugsee/react-native` app: React Native 0.81 or later with the New Architecture, Hermes, iOS 15.0 or later and Android API 21 or later. Any Expo SDK whose React Native is 0.81 or later meets this; the package's own Expo example uses Expo SDK 57 with React Native 0.86. The plugin edits Groovy Gradle files only; see [Limits](#limits). + +:::caution[No Expo Go] +The package contains native code, so it does not run in Expo Go: the native module is looked up when the package loads, and is missing there. Use a [development build](https://docs.expo.dev/develop/development-builds/introduction/) instead. +::: + +## 1. Add the package + +```sh +yarn add @bugsee/react-native@beta +``` + +`npm install` and `pnpm add` work the same way; see [Installation](/sdk/react_native/installation#1-add-the-package), including the [pnpm notes](/sdk/react_native/installation#pnpm). + +## 2. Add the plugin + +Add `@bugsee/react-native` to `plugins` in `app.json` (or `app.config.js`): + +```json title="app.json" +{ + "expo": { + "plugins": [ + ["@bugsee/react-native", { "appToken": { "ios": "YOUR_IOS_APP_TOKEN", "android": "YOUR_ANDROID_APP_TOKEN" } }] + ] + } +} +``` + +`appToken` is either one string for both platforms or one token per platform. Bugsee app tokens are per platform, so the object form is the usual one. A token may contain only letters, digits, `.`, `_` and `-`; anything else, such as a placeholder like ``, fails the prebuild. + +## 3. Run prebuild + +```sh +npx expo prebuild +``` + +Run it again whenever you change the plugin's options. The plugin's edits are its own: a later prebuild with a new value replaces them, and one without an option removes what that option wrote, with one exception. Turning `autoLaunch` off does not remove the `com.bugsee.app-token` entry that an earlier prebuild added to `AndroidManifest.xml`, so the SDK would still start before your code calls `Bugsee.launch`. After turning `autoLaunch` off, run a clean prebuild (`npx expo prebuild --clean`) or delete that entry yourself. + +Release builds then upload their source maps, and Archives upload their dSYMs, whenever a real token is set. + +:::caution[7.0.0-beta1 and 7.0.0-beta2: Android Release builds need `chmod`] +In 7.0.0-beta1 and 7.0.0-beta2 the package's shell scripts are published without the executable bit. The `hermesCommand` the plugin writes runs `hermesc-preserve-js.sh` directly, so an Android Release build on macOS or Linux fails with "Permission denied". Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` after each install, for example from a `postinstall` script; see [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps). The iOS bundle phase the plugin writes runs its script through `/bin/bash` and is not affected. +::: + +## 4. Launch the SDK + +Launch from JavaScript as in a bare app: + +```ts title="index.js" +import { Platform } from 'react-native'; +import Bugsee, { createDefaultLaunchOptions } from '@bugsee/react-native'; + +Bugsee.launch( + Platform.OS === 'ios' ? 'YOUR_IOS_APP_TOKEN' : 'YOUR_ANDROID_APP_TOKEN', + createDefaultLaunchOptions(), +); +``` + +See [Installation](/sdk/react_native/installation#4-launch-bugsee) for what `launch` does and resolves to, and [Configuration](/sdk/react_native/configuration) for the options. To have Android start the SDK before JavaScript runs instead, see [`autoLaunch`](#auto-launch-on-android). + +## Plugin options + +| Option | Type | Default | What it does | +| --- | --- | --- | --- | +| `appToken` | string, or `{ ios?: string; android?: string }` | none | The token the build uploads use. Android: `app_token` in `android/bugsee.properties`. iOS: written into the Archive dSYM post-action, and into the bundle phase when `uploadSourcemaps` is on, so an Archive started from the Xcode GUI, which does not inherit a shell environment, still has it. A value that is not token-shaped fails the prebuild. | +| `uploadSourcemaps` | boolean | `true` | Upload the composed JavaScript source map of Release builds. `false` writes `bugseeUploadSourcemaps=false` into `android/gradle.properties` and `BUGSEE_UPLOAD_SOURCEMAPS=false` into the iOS bundle phase. | +| `uploadSymbols` | boolean | `true` | Upload native symbols. `false` removes the iOS Archive dSYM post-action (including one an earlier prebuild left) and, on Android, disables the Bugsee Gradle plugin's `uploadBugsee*` tasks (R8 mapping, NDK symbols, build info) in a marked block. Source maps follow `uploadSourcemaps`. | +| `nativeCrashReporting` | boolean | `true` | Android native (NDK) crash reporting. On: writes `plugin.ndk.enabled=true` for a real token and adds `com.bugsee:bugsee-android-ndk`. `false`: skips the flag, removes that dependency and excludes the package's NDK artifact. | +| `symbolicateReactNativeFrameworks` | boolean | `false` | Make `pod install` download React Native's own dSYMs, so React frames in iOS crashes symbolicate. See [React Native's dSYMs](#react-native-dsyms-on-ios). | +| `autoLaunch` | boolean | `false` | Android only. Writes the `com.bugsee.app-token` manifest meta-data, so the native SDK launches at process start. See [Auto-launch on Android](#auto-launch-on-android). | +| `endpoint` | string | none (production) | A self-hosted, staging or regional Bugsee API base. See [Custom endpoint](#custom-endpoint). | +| `gradlePluginVersion` | string | the version the package is built against (4.0.8 in `7.0.0-beta2`) | The `com.bugsee.android.gradle` version to declare. | + +## What the plugin changes + +### Android + +- **`android/settings.gradle`**: adds `mavenCentral()` to `pluginManagement { repositories { … } }`. The Bugsee Gradle plugin is published to Maven Central, which Gradle does not search for plugins unless told to. If there is no `repositories` block, it adds the Gradle Plugin Portal, Google and Maven Central together, since declaring any block replaces Gradle's implicit Plugin Portal. +- **`android/build.gradle`**: declares `com.bugsee.android.gradle` with `apply false`, at the plugin's version. A declaration that is already there, whoever wrote it, is taken as the plugin's own pin and its version follows the package's on each prebuild. +- **`android/app/build.gradle`**: applies `com.bugsee.android.gradle`, points `react.hermesCommand` at the package's Hermes wrapper (which keeps the JavaScript so the debug id can reach the bytecode), applies the package's `scripts/bugsee-sourcemaps.gradle`, and adds the NDK dependency unless `nativeCrashReporting` is `false`. +- **`android/bugsee.properties`**: `app_token`, `plugin.ndk.enabled` and `plugin.endpoint`, as the options set them. A missing or placeholder token is left out. +- **`android/gradle.properties`**: `bugseeUploadSourcemaps=false` when `uploadSourcemaps` is `false`. +- **`AndroidManifest.xml`**: the `com.bugsee.app-token` meta-data with `autoLaunch`, and the endpoint meta-data with `endpoint`. + +The plugin never removes or changes a line of your own code, on a clean or a `--no-clean` prebuild. It adds its own marked lines, replaces only those, and rewrites exactly one of yours, `react.hermesCommand`, keeping any trailing comment. A `bugsee-android-ndk` dependency of your own is never touched: the plugin then adds none and says so in the prebuild log. + +The plugin writes no `ndk { debugSymbolLevel … }`: the Bugsee Gradle plugin uploads native symbols from the unstripped libraries, whatever that level says, so it is your own choice for Google Play. Earlier versions of the config plugin wrote a `SYMBOL_TABLE` block under a `// bugsee-symbol-table:` comment; the next prebuild removes it if you have not changed it. + +### iOS + +- **"Bundle React Native code and images" build phase**: the call to React Native's `react-native-xcode.sh` is swapped for the package's `bugsee-xcode.sh`, which runs React Native's script, then composes the Hermes source map, gives the bundle and the map a debug id, and uploads the map. The rest of Expo's phase stays as it is. +- **Shared schemes**: an Archive post-action that uploads the dSYMs with `bugsee-cli`, in every shared scheme under `ios/`. Without a real token it stops before it runs `bugsee-cli`. +- **`Info.plist`**: `BugseeReactNativeEndpoint` when `endpoint` is set. +- **`Podfile`**: a marked `# @generated begin bugsee-symbolicate-prebuilt` … `# @generated end bugsee-symbolicate-prebuilt` block with `symbolicateReactNativeFrameworks`. + +### Uploads without a token + +No upload runs with a missing token or the placeholder token (`00000000-0000-4000-8000-000000000000`). The source-map upload, the Archive dSYM post-action and the Bugsee Gradle plugin's mapping, symbol and build uploads each skip with one line in the build log, and the build or Archive carries on. For the post-action, the line is: + +```text +warning: bugsee: dSYM upload skipped: the app token is the placeholder +``` + +A failed source-map upload warns and does not fail the build. + +:::note[Committed native projects] +If you commit `ios/` (`project.pbxproj` and the shared scheme) or `android/bugsee.properties`, they carry the token. Keep `android/bugsee.properties` out of version control if the token is private. +::: + +## Auto-launch on Android + +With `autoLaunch: true` and a real Android token, the plugin writes the token as `com.bugsee.app-token` application meta-data. The SDK then launches itself at process start on Android, before any JavaScript runs. + +```json title="app.json" +["@bugsee/react-native", { "appToken": { "ios": "YOUR_IOS_APP_TOKEN", "android": "YOUR_ANDROID_APP_TOKEN" }, "autoLaunch": true }] +``` + +On Android, do not call `Bugsee.launch` then. The SDK is already running, so `launch` would resolve `true` but not apply its options (logging a warning to logcat when the call carries options), while the JavaScript side applied them; see [Launching again](/sdk/react_native/lifecycle#launching-again). Call `Bugsee.attach()` instead, which wires up the JavaScript layer (exception handlers and console capture) from the options the SDK is running with. See [Attach to a running SDK](/sdk/react_native/lifecycle#attach-to-a-running-sdk). + +```ts +import { Platform } from 'react-native'; +import Bugsee from '@bugsee/react-native'; + +if (Platform.OS === 'android') { + Bugsee.attach(); +} else { + Bugsee.launch('YOUR_IOS_APP_TOKEN'); +} +``` + +iOS has no auto-launch: launch it from JavaScript. A placeholder token is never written to the manifest. + +Two consequences of auto-launch on Android: + +- **Launch options from JavaScript are not applied.** The SDK starts from the manifest, before your options object exists. Configure it with `com.bugsee.option.*` application meta-data in `AndroidManifest.xml` (in an Expo app, through a config plugin of your own; the Bugsee plugin writes none), or call `Bugsee.relaunch(options)` after `attach()` to restart the session with your options. +- **Reports lack the JavaScript details.** At process start the package registers only the React Native SDK type and version. `launch` and `relaunch` replace that with the full identity (React Native version, JavaScript engine, development build), but `attach()` does not, so until a `relaunch`, the session's reports carry the React Native wrapper type and version without those details. + +## Custom endpoint + +To send everything to a self-hosted, staging or regional Bugsee API, set `endpoint`: + +```json title="app.json" +["@bugsee/react-native", { "appToken": "YOUR_APP_TOKEN", "endpoint": "https://bugsee.example.com" }] +``` + +The value is the API base: `https://`, a host, an optional port and an optional path, with no credentials, query, fragment or `/v2` (each reader adds the API version itself). Anything else fails the prebuild. Unset, the default, everything stays on Bugsee's production API. + +Set, it reaches every upload and the runtime: + +- **Android**: `plugin.endpoint` in `android/bugsee.properties`, for the Gradle plugin's uploads and the source-map upload, and `com.bugsee.reactnative.endpoint` application meta-data for the SDK. +- **iOS**: `BUGSEE_ENDPOINT` in the bundle phase (source maps, when `uploadSourcemaps` is on) and in the Archive dSYM post-action, and `BugseeReactNativeEndpoint` in `Info.plist` for the SDK. +- **Runtime**: `Bugsee.launch()` and `relaunch()` use it whenever their options carry no endpoint; an endpoint you pass yourself wins. `getLaunchOptions()` reads it back. With `autoLaunch`, it is also written as the auto-launched SDK's `com.bugsee.option.$$ENDPOINT`, unless your manifest already has one, which is then left as it is. + +## React Native dSYMs on iOS + +React Native's prebuilt `React.xcframework` ships without dSYMs, so after an Archive the `React` frames in a crash stay raw addresses while your own and Bugsee's frames symbolicate. React Native downloads the dSYMs only when `pod install` runs with `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1`. + +```json title="app.json" +["@bugsee/react-native", { "appToken": "YOUR_IOS_APP_TOKEN", "symbolicateReactNativeFrameworks": true }] +``` + +`expo prebuild` then adds `ENV['RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS'] ||= '1'` to the top of `ios/Podfile`, and a later prebuild without the option removes it. A value you export yourself, such as `0`, wins. + +It is off by default because of the trade-off: `pod install` makes an extra download, and React Native fetches the dSYMs in the same step as the prebuilt framework, so a failed download drops the prebuilt React for that install, and a failure while unpacking aborts `pod install`. The variable also does nothing for a `React-Core-prebuilt` pod already in `ios/Pods` or the CocoaPods cache; see [Symbolication: iOS](/sdk/react_native/symbolication/ios). + +## Limits + +Where the plugin cannot make an edit with certainty, it refuses the prebuild with one error that names the file, the reason and the fix, and writes nothing. It refuses: + +- a Kotlin DSL `settings.gradle.kts`, `build.gradle.kts` or app `build.gradle.kts`. The refusal does not depend on what the file contains, so making the edits by hand does not get past it, whatever the error message suggests. With Kotlin DSL files, remove `@bugsee/react-native` from `plugins`, which also drops its iOS edits, and make every edit by hand, as in [Symbolication: Android](/sdk/react_native/symbolication/android) and [Symbolication: iOS](/sdk/react_native/symbolication/ios); +- a Gradle file it cannot read for sure: a string that does not close on its line, a comment or string still open at the end of the file, braces that do not balance, or a `/` that could start a slashy string as well as divide; +- a `react.hermesCommand` that spans several lines or shares its line with another statement after `;`; +- an anchor brace that shares its line with code: a one-line `dependencies { … }`, a `buildscript { … }; …`, or a one-line `pluginManagement` or `repositories` block; +- a `gradlePluginVersion` option, or an NDK version baked into the package, that is not a plain version string. + +On iOS, the prebuild fails when there is no shared `.xcscheme` under `ios/`, because the dSYM post-action goes into the shared schemes. + +The feedback package, `@bugsee/react-native-feedback`, needs no config plugin; see [Feedback](/sdk/react_native/feedback). + +## Related pages + +- [Installation](/sdk/react_native/installation): requirements and launching the SDK. +- [Symbolication](/sdk/react_native/symbolication/overview): what each upload is for. +- [Lifecycle & status](/sdk/react_native/lifecycle): `launch`, `attach` and status. diff --git a/sidebars.ts b/sidebars.ts index fee8551..4085e0f 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -566,6 +566,11 @@ const sidebars: SidebarsConfig = { id: "sdk/react_native/installation", label: "Installation", }, + { + type: "doc", + id: "sdk/react_native/expo", + label: "Expo", + }, ], }, { From 9a71c31268cfa18fe243fd13ba1b28052e4611a3 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:55:43 +0500 Subject: [PATCH 06/49] docs(react-native): Configuration (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Launch options: the options object and plain map, createDefaultLaunchOptions, shared/Android/iOS accessors, setCustomOption, the shared and platform-only com.bugsee.option.* keys, enums, the per-platform endpoint, getLaunchOptions and refreshFrom. Verified against packages/react-native/src/options/* (including option-keys.json and android-options-manifest.json) and BugseeOptionEnums.java. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I05a4ca95965d1856c10fbe20b01cab5a772fdcd8 --- cspell.json | 6 +- docs/sdk/react_native/configuration.mdx | 370 ++++++++++++++++++++++++ sidebars.ts | 5 + 3 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/react_native/configuration.mdx diff --git a/cspell.json b/cspell.json index 5363f31..839447a 100644 --- a/cspell.json +++ b/cspell.json @@ -234,6 +234,10 @@ "Podspec", "javascriptcore", "reactnative", - "slashy" + "slashy", + "avplayer", + "ABRT", + "SEGV", + "oslog" ] } \ No newline at end of file diff --git a/docs/sdk/react_native/configuration.mdx b/docs/sdk/react_native/configuration.mdx new file mode 100644 index 0000000..c1ac95f --- /dev/null +++ b/docs/sdk/react_native/configuration.mdx @@ -0,0 +1,370 @@ +--- +title: "Configuration" +description: "The launch options of Bugsee React Native SDK 7.x: the options object and its accessors, the shared com.bugsee.option.* keys, enums, the endpoint, and reading the effective options back." +sidebar_position: 3 +slug: "/sdk/react_native/configuration" +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +You configure the SDK with the options you pass to `Bugsee.launch` (and later `Bugsee.relaunch`). The same `com.bugsee.option.*` keys work on both platforms, so there is no per-platform key mapping: apart from the endpoint the Expo plugin can supply, the options you pass are the options the SDK applies, on both platforms. Enum-typed options take numbers; see [Enum reference](#enum-reference). + +## Two ways to pass options + +`launch` and `relaunch` accept either form, and both have the same effect: + +- **The options object**, from `createDefaultLaunchOptions()`, with typed accessors. Pass it as is; there is no serialize step to call. +- **A plain map** of `com.bugsee.option.*` keys, for options you build or merge yourself. + + + + +```ts +import Bugsee, { createDefaultLaunchOptions, LogLevel } from '@bugsee/react-native'; + +const options = createDefaultLaunchOptions(); +options.duration = 120; +options.captureLogsLevel = LogLevel.Info; +options.wifiOnlyUpload = true; + +Bugsee.launch(token, options); +``` + + + + +```ts +import Bugsee, { LogLevel } from '@bugsee/react-native'; + +Bugsee.launch(token, { + 'com.bugsee.option.config.duration': 120, + 'com.bugsee.option.capture.logs.level': LogLevel.Info, + 'com.bugsee.option.config.wifi-only-upload': true, +}); +``` + + + + +`BugseeLaunchOptions.serialize(options)` returns the plain map an options object stands for, as a snapshot: a later change to the object does not change a map you already took. + +## The options object + +`createDefaultLaunchOptions()` returns an empty options object for the running platform: an `IOSLaunchOptions` on iOS, an `AndroidLaunchOptions` on Android. Pass a platform (`'ios'` or `'android'`) to get the other one; any other platform throws. + +The object is **not** pre-filled with defaults. An option you leave unset is not sent at all, so the native SDK applies its own default. Setting an accessor to `undefined` removes the key again, rather than sending an empty value that would override the default. + +Accessors shared by both platforms live on the base class, `BugseeLaunchOptions`. Platform-only accessors live on `AndroidLaunchOptions` and `IOSLaunchOptions`, so an iOS-only option cannot be set on an Android options object by accident. To reach one, narrow the object first: + +```ts +import { + AndroidLaunchOptions, + IOSLaunchOptions, + createDefaultLaunchOptions, +} from '@bugsee/react-native'; + +const options = createDefaultLaunchOptions(); +if (options instanceof AndroidLaunchOptions) { + options.triggerByNotification = false; +} else if (options instanceof IOSLaunchOptions) { + options.captureDiskSpace = true; +} +``` + +### Any key: `setCustomOption` + +`setCustomOption(key, value)` sets any option by its real `com.bugsee.option.*` key, whether or not it has an accessor. A custom key and an accessor write to the same map, so an option that has no accessor yet, including one added in a later 7.x native release, is reachable without a new release of this package. `undefined` removes the key, as with an accessor. + +```ts +options.setCustomOption('com.bugsee.option.detect.http-errors', true); +options.setCustomOption('com.bugsee.option.capture.network.body-size-limit', 10240); +``` + +## Shared accessors + +These accessors exist on both platforms. + +| Accessor | Key | Type | Default | Description | +| --- | --- | --- | --- | --- | +| `duration` | `com.bugsee.option.config.duration` | number (seconds) | `60` | Length of the rolling capture buffer (video, logs, breadcrumbs). | +| `wifiOnlyUpload` | `com.bugsee.option.config.wifi-only-upload` | boolean | `false` | Defer report uploads until the device is on Wi-Fi. | +| `maxDataSize` | `com.bugsee.option.config.max-data-size` | number (MB) | `150` (Android) / `50` (iOS) | Disk space that reports waiting to be sent may take. Enforced on Android. On iOS this beta accepts the key but does not enforce it. See [Automatic retention](/sdk/react_native/privacy/cleanup#automatic-retention). | +| `captureVideo` | `com.bugsee.option.capture.video` | boolean | `true` | Record the screen for reports. | +| `captureNetwork` | `com.bugsee.option.capture.network` | boolean | `true` | Record network requests and responses. | +| `captureLogs` | `com.bugsee.option.capture.logs` | boolean | `true` | Capture logs automatically, including `console.*` output. `false` stops console forwarding; lines you send with `Bugsee.log` are still recorded. | +| `captureLogsLevel` | `com.bugsee.option.capture.logs.level` | `LogLevel` | `Verbose` | The most verbose level captured; less severe lines are dropped. `LogLevel.Info` keeps `Error`, `Warning` and `Info`. | +| `captureBreadcrumbs` | `com.bugsee.option.capture.breadcrumbs` | boolean | `false` | Record breadcrumbs. While off, `Bugsee.addBreadcrumb` records nothing, on both platforms. | +| `detectAndReportCrash` | `com.bugsee.option.detect.crash` | boolean | `true` | Report crashes. `false` also turns off the reporting of uncaught JavaScript errors, unhandled promise rejections and uncaught render errors. See [Turning automatic reporting off](/sdk/react_native/manual/crash-error-reporting#turning-automatic-reporting-off). | +| `detectAndReportHang` | `com.bugsee.option.detect.hang` | boolean | `false` | Report when the main thread is blocked long enough to count as a hang. | + +The **Default** column applies to both platforms unless the row gives one per platform. Read the values in effect with [`getLaunchOptions()`](#reading-the-effective-options). + +## Android accessors + +`AndroidLaunchOptions` adds these. + +| Accessor | Key | Type | Default | Description | +| --- | --- | --- | --- | --- | +| `endpoint` | `com.bugsee.option.$$ENDPOINT` | string | production | API endpoint override; see [Endpoint](#endpoint). | +| `videoMode` | `com.bugsee.option.capture.video.mode` | `VideoMode` | `V2` | Screen-capture strategy. | +| `logsUseAllSources` | `com.bugsee.option.capture.logs.allsources` | boolean | `false` | Read all logcat buffers instead of the default sources. | +| `detectAndReportExitLowMemory` | `com.bugsee.option.detect.exit.low_memory` | boolean | `true` | Report exits where the OS killed the app to reclaim memory. | +| `detectAndReportExitLowMemoryBackgroundAsError` | `com.bugsee.option.detect.exit.bg_low_memory_as_error` | boolean | `false` | Report a low-memory kill of a process that was not in the foreground as a non-fatal error rather than a crash. Applies only while `detectAndReportExitLowMemory` is on. | +| `maxPendingReports` | `com.bugsee.option.config.max-pending-reports` | number | `30` | Most reports kept waiting to be sent. | +| `maxPendingReportAge` | `com.bugsee.option.config.max-pending-report-age` | number (days) | `30` | Oldest a report waiting to be sent may get; `0` or less keeps reports until they are sent or evicted. | +| `triggerByNotification` | `com.bugsee.option.reporting.triggers.notification-bar` | boolean | `true` | Show a notification-bar entry that opens the report UI. | + +The other Android-only keys are reachable with `setCustomOption`: see [Platform-only keys](#platform-only-keys). + +## iOS accessors + +`IOSLaunchOptions` adds these. + +| Accessor | Key | Type | Default | Description | +| --- | --- | --- | --- | --- | +| `endpoint` | `endpoint` | string | production | API endpoint override; see [Endpoint](#endpoint). Not a `com.bugsee.option.*` key on iOS. | +| `captureAVPlayer` | `com.bugsee.option.capture.avplayer` | boolean | `false` | Capture video that plays through `AVPlayerLayer` and `AVPlayerViewController` in the recording. | +| `captureDiskSpace` | `com.bugsee.option.capture.disk-space` | boolean | `false` | Monitor available disk space and include it in reports as a system trace and device properties. | +| `crashHandlerType` | `com.bugsee.option.capture.crash-handler-type` | `CrashHandlerType` | `MachAndBSD` | How the crash reporter intercepts crashes. | +| `crashSignals` | `com.bugsee.option.capture.crash-signals` | number (bit set) | every signal | The fatal signals the crash reporter intercepts: `ABRT` 1, `SEGV` 2, `BUS` 4, `ILL` 8, `FPE` 16, `TRAP` 32. Add the values to combine them. | + +## Other shared keys + +These keys are accepted by both native SDKs but have no accessor. Set them with `setCustomOption`, or in a plain map. Type and default are the same on both platforms, except where a row gives one per platform. + +### Detection + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `com.bugsee.option.detect.early-crash` | boolean | `true` | Also catch crashes very early in startup. | +| `com.bugsee.option.detect.exit` | boolean | `true` | Detect and report application exits. | +| `com.bugsee.option.detect.hang.level.fair` | number (ms) | `3000` | Main-thread block that counts as a "Fair" hang. | +| `com.bugsee.option.detect.hang.level.medium` | number (ms) | `5000` | Main-thread block that counts as a "Medium" hang. | +| `com.bugsee.option.detect.hang.level.severe` | number (ms) | `10000` | Main-thread block that counts as a "Severe" hang. | +| `com.bugsee.option.detect.http-errors` | boolean | `false` | Turn HTTP 5xx responses into error reports. | +| `com.bugsee.option.detect.main_thread_misuse` | boolean | `false` | Report file, network or database work done on the main thread. | +| `com.bugsee.option.detect.anomaly` | boolean | `false` | The statistical performance-anomaly detector. | +| `com.bugsee.option.detect.frustration` | boolean | `false` | Detect user-frustration patterns such as rage taps and report them. | + +### Capture + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `com.bugsee.option.capture.screenshot` | boolean | `true` | Take a screenshot when a report is created. | +| `com.bugsee.option.capture.screenshot.scale` | number | `1` | Down-then-up scaling of the screenshot, which destroys fine detail; `1` turns it off. | +| `com.bugsee.option.capture.view-hierarchy` | boolean | `true` | Capture the view hierarchy for reports (also needs [`Bugsee.wrap`](/sdk/react_native/installation#4-launch-bugsee)). | +| `com.bugsee.option.capture.breadcrumbs.extras` | boolean | `false` | Attach raw system data to the breadcrumbs the native SDK records for system events: the `Intent` extras of system broadcasts on Android, the notification `userInfo` of device events on iOS. | +| `com.bugsee.option.capture.video.quality` | `VideoQuality` | `Default` | Quality of the encoded video. | +| `com.bugsee.option.capture.video.frame-rate` | `FrameRate` | `High` | How often frames are captured. | +| `com.bugsee.option.capture.video.scale` | number | `1` | Extra down-scaling of the recorded video, for example `0.5`. | +| `com.bugsee.option.capture.video.adaptive` | boolean | `false` (Android) / `true` (iOS) | Skip frames while nothing on screen has been redrawn. | +| `com.bugsee.option.capture.network.on-launch` | boolean | `false` | Start network capture during `launch` instead of when capture starts, so startup requests are not missed. | +| `com.bugsee.option.capture.network.body-size-limit` | number (bytes) | `20480` | Largest request or response body captured. | +| `com.bugsee.option.capture.network.body-without-type` | boolean | `false` | Also keep bodies that declare no content type. | +| `com.bugsee.option.capture.network.default-sanitizer` | boolean | `true` | Redact known sensitive keys in URLs, headers and JSON bodies. See [Privacy: Network](/sdk/react_native/privacy/network) for how it combines with a network filter on each platform. | + +### Reporting + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `com.bugsee.option.reporting.triggers.shake` | boolean | `true` | Open the report UI when the device is shaken. | +| `com.bugsee.option.reporting.triggers.screenshot` | boolean | `false` | Open the report UI when the user takes a screenshot. | +| `com.bugsee.option.reporting.defaults.crash-priority` | `IssueSeverity` | `Blocker` | Severity of crash reports. | +| `com.bugsee.option.reporting.defaults.error-priority` | `IssueSeverity` | `High` | Severity of error reports. | +| `com.bugsee.option.reporting.defaults.bug-priority` | `IssueSeverity` | `High` | Severity of bug reports. | +| `com.bugsee.option.reporting.ui.summary-required` | boolean | `false` | Make the Summary field mandatory. | +| `com.bugsee.option.reporting.ui.description-required` | boolean | `false` | Make the Description field mandatory. | +| `com.bugsee.option.reporting.ui.email-required` | boolean | `false` | Make the Email field mandatory. | +| `com.bugsee.option.reporting.ui.labels-enabled` | boolean | `false` | Show the Labels field. | +| `com.bugsee.option.reporting.ui.labels-required` | boolean | `false` | Make the Labels field mandatory. | +| `com.bugsee.option.reporting.ui.priority-selector-enabled` | boolean | `false` | Let the user pick the priority. | + +### Upload and performance + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `com.bugsee.option.config.notify-flush-delay` | number (ms) | `0` | Coalescing window before queued `Bugsee.notify` items are sent. | +| `com.bugsee.option.performance.enabled` | boolean | `true` | Master switch for performance monitoring; see [Performance monitoring](/sdk/react_native/performance). | +| `com.bugsee.option.performance.sample-rate` | number `[0, 1]` | `0.01` | Probability that a transaction is sampled for a standalone upload, which is not active in this beta; see [Sampling](/sdk/react_native/performance#sampling). | +| `com.bugsee.option.performance.adaptive-sampling` | boolean | `true` | Promote unsampled transactions that look interesting into the standalone upload, which is not active in this beta. | + +## Platform-only keys + +Keys for native WebView capture, shared or platform-only, are omitted from this page and from the shared tables above. + +Some keys are accepted by one SDK only; the other SDK does not recognize them. `setCustomOption` does not check the platform, so set these only on the platform they belong to. + +**Android only.** Native SDK reference: [Android configuration](/sdk/android/configuration). + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `com.bugsee.option.capture.respect-flag-secure` | boolean | `true` | Protect windows that set `FLAG_SECURE`: they are blanked in the video and screenshots and left out of the view hierarchy. See [Privacy: Video](/sdk/react_native/privacy/video). | +| `com.bugsee.option.capture.video.custom-muxer` | boolean | `false` | Encode the video with Bugsee's own MP4 muxer instead of the system one. | +| `com.bugsee.option.capture.video.fullscreen-keep-running` | boolean | `true` | With `VideoMode.Fullscreen`, keep screen capture running in the background, rather than stopping it and asking the user again on return. | +| `com.bugsee.option.capture.video.fullscreen-remember-decision` | boolean | `true` | With `VideoMode.Fullscreen`, remember the user's screen-capture consent across launches. | +| `com.bugsee.option.capture.video.secure-scrolling` | boolean | `false` | With `VideoMode.V1`, skip more frames while secure views are on screen. | +| `com.bugsee.option.config.report-handler-callback-timeout` | number (seconds) | `30` | Lowers the report handler deadline; see [Report handler](/sdk/react_native/report-handler#async-callbacks-and-deadlines). | +| `com.bugsee.option.config.report-processing-in-process` | boolean | `true` | Assemble and upload reports in the app's process. `false` schedules them as system jobs, which survive the process at the cost of upload latency. | +| `com.bugsee.option.detect.anr.sampling` | boolean | `true` | Sample the main thread during an ANR, to attribute the report to the frames that were blocking. | +| `com.bugsee.option.detect.hang.sampling` | boolean | `true` | The same for hangs, while `detectAndReportHang` is on. | +| `com.bugsee.option.detect.exit.not_responding` | boolean | `true` | Report exits after the app stopped responding (ANR). | +| `com.bugsee.option.detect.exit.not_responding.as_crash` | boolean | `false` | Report those exits as crashes rather than errors. | +| `com.bugsee.option.detect.exit.*`: `dependency_died`, `excessive_resource_usage`, `other`, `package_state_changed`, `package_updated`, `permission_changed`, `unknown`, `user_requested`, `user_was_stopped` | boolean | `false` | Report exits for that reason too. | +| `com.bugsee.option.performance.upload-mode` | string | `"batched"` | How a standalone performance upload would send data; that upload is not active in this beta. | +| `com.bugsee.option.reporting.triggers.broadcast` | boolean | `false` | Let a broadcast intent open the report dialog. | + +**iOS only**, beyond the accessors above. Native SDK reference: [iOS configuration](/sdk/ios/configuration#available-options), which lists the options under their 6.x names, and the [iOS 7.x migration guide](/sdk/ios/v7/migration#2-option-keys), which maps them to these keys. + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `com.bugsee.option.capture.bluetooth-status` | boolean | `false` | Monitor the Bluetooth state. Needs `NSBluetoothAlwaysUsageDescription` in `Info.plist`. | +| `com.bugsee.option.capture.camera-preview` | boolean | `false` | Record the live camera image shown in an `AVCaptureVideoPreviewLayer`. This records whatever the camera sees, and adds work to your camera session. Off, a camera preview records as an empty rectangle. | +| `com.bugsee.option.capture.device-network-names` | boolean | `false` | Capture the device name, the Wi-Fi network name and the mobile carrier name. | +| `com.bugsee.option.capture.logs.oslog` | boolean | `false` | Accepted and ignored in this beta: `os_log` entries are not captured. | +| `com.bugsee.option.capture.on-device-symbolication` | boolean | `false` | Symbolicate crash stack frames on the device. | +| `com.bugsee.option.capture.sample-buffer-display-layer` | boolean | `false` | Capture video shown through an `AVSampleBufferDisplayLayer` in the recording (pixel-buffer samples only). | +| `com.bugsee.option.capture.status-bar-info` | boolean | `false` | On-screen status indicators for testing the SDK itself. No effect in release builds of the SDK. | +| `com.bugsee.option.capture.video.max-frame-rate` | number (fps) | `0` | Highest capture frame rate. `0` uses the rate `capture.video.frame-rate` picks. | +| `com.bugsee.option.capture.video.min-frame-rate` | number (fps) | `0` | Lowest capture frame rate. `0` uses the rate `capture.video.frame-rate` picks. | +| `com.bugsee.option.capture.video.privacy-blur` | boolean | `true` | Blur the frames of a screen transition instead of leaving them out. `false` freezes the video for the transition. | +| `com.bugsee.option.capture.websocket` | boolean | `true` | Record WebSocket traffic; see [Network events](/sdk/react_native/network#websocket-traffic). | +| `com.bugsee.option.config.build-target` | string | none | Build target name, sent with reports. | +| `com.bugsee.option.config.build-type` | string | none | Build type, such as `debug` or `release`, sent with reports. | +| `com.bugsee.option.config.data-encryption` | number | `0` | Encryption of the collected data: `0` none, `1` on device (keys kept in the Secure Enclave), `2` end to end (decrypted only on the server, so some features, such as the video preview, are missing). The package exports no constants for it. | +| `com.bugsee.option.detect.crash.fill_empty_exception_stacks` | boolean | `false` | Fill in the stack of an uncaught `NSException` that has none from the crashing thread. This can change how crashes are grouped. | +| `com.bugsee.option.detect.crash.swift_async_stacktraces` | boolean | `true` | Stitch Swift async frames into the stacks of C++ exceptions. | +| `com.bugsee.option.reporting.ui.style` | number | `3` | Style of the report UI: `0` Light, `1` Dusk, `2` based on the status bar, `3` the system style. The package exports no constants for it. | + +## Enum reference + +Enum-typed options take a number. Use the exported constants rather than writing numbers: the values are each enum's internal value in the native SDKs, not its position in the list, so `LogLevel.Error` is `1` and `VideoMode.Fullscreen` is `20`. + +```ts +import { FrameRate, IssueSeverity, VideoQuality } from '@bugsee/react-native'; + +options.setCustomOption('com.bugsee.option.capture.video.frame-rate', FrameRate.Medium); +options.setCustomOption('com.bugsee.option.capture.video.quality', VideoQuality.High); +options.setCustomOption('com.bugsee.option.reporting.defaults.bug-priority', IssueSeverity.Critical); +``` + +| Enum | Values | Used by | +| --- | --- | --- | +| `LogLevel` | `Error` 1, `Warning` 2, `Info` 3, `Debug` 4, `Verbose` 5 | `captureLogsLevel`, `Bugsee.log` | +| `VideoMode` | `None` 0, `V1` 1, `V2` 2, `Fullscreen` 20, `DirectBuffers` 21 | `videoMode` (Android) | +| `VideoQuality` | `Default` 0, `Medium` 1, `High` 2 | `capture.video.quality` | +| `FrameRate` | `Low` 1, `Medium` 2, `High` 3 | `capture.video.frame-rate` | +| `IssueSeverity` | `VeryLow` 1, `Medium` 2, `High` 3, `Critical` 4, `Blocker` 5 | `reporting.defaults.*-priority`, report severities | +| `CrashHandlerType` | `BSD` 1, `Mach` 2, `MachAndBSD` 3 | `crashHandlerType` (iOS) | + +- `FrameRate` has no `Raw`: only Android has that rate, and the same number would mean different capture rates on the two platforms. +- `CrashHandlerType` is iOS only. `BSD` uses BSD signal handlers. `Mach` uses a Mach exception handler plus a BSD handler for `SIGABRT`; other signals raised by software (`raise()`, `kill()`) are not reported. `MachAndBSD`, the default, uses both, so hardware faults and signals raised by software are reported. + +A number that names no value of the enum is handled differently on each platform. Android: it is dropped (as is a number that is not whole), so the option keeps its default. iOS: it is not checked, and is applied as given. Use the exported constants. + +## Value types + +Option values are booleans, numbers and strings. Other values are dropped without an error. Android: any value that is not one of those three types (an array, an object or `null`). iOS: a value whose type does not fit its key (a string for a boolean key, say). The option then keeps its default. + +## Endpoint + +The endpoint override is the one option whose key differs per platform, which is why `endpoint` is an accessor on `AndroidLaunchOptions` and `IOSLaunchOptions` rather than on the base class. Set it on the object returned by `createDefaultLaunchOptions()` and the right key is written: + +```ts +const options = createDefaultLaunchOptions(); +options.endpoint = 'https://bugsee.example.com'; +``` + +| Platform | Key | What is sent | +| --- | --- | --- | +| Android | `com.bugsee.option.$$ENDPOINT` | The value, trimmed. Accepted with or without `/v2`. | +| iOS | `endpoint` | The value, trimmed, without trailing slashes, with `/v2` added unless it already ends in `/v2`. | + +The `endpoint` getter returns what will be sent, so on iOS it reads back with `/v2`. An empty or blank value removes the override. + +For a plain map, `endpointFor(platform, endpoint)` returns the entry to merge in, or `{}` for an empty value: + +```ts +import { Platform } from 'react-native'; +import Bugsee, { endpointFor } from '@bugsee/react-native'; + +Bugsee.launch(token, { + 'com.bugsee.option.config.duration': 60, + ...endpointFor(Platform.OS === 'ios' ? 'ios' : 'android', 'https://bugsee.example.com'), +}); +``` + +An Expo app can set the endpoint once in the [config plugin](/sdk/react_native/expo#custom-endpoint) instead. `launch` and `relaunch` then use it whenever their options carry no endpoint; an endpoint you pass yourself wins. + +## Reading the effective options + +`Bugsee.getLaunchOptions()` resolves to the options the native SDK reports as in effect, as a plain `com.bugsee.option.*` map, including the SDK's defaults for what you did not set: + +```ts +async function logDuration() { + const effective = await Bugsee.getLaunchOptions(); + console.log(effective['com.bugsee.option.config.duration']); +} +``` + +Both platforms answer before launch too, with the defaults. + +An options object's getters return what you set on it, and nothing else, until you load the reported options into it. `BugseeLaunchOptions.refreshFrom(options, reported)` installs them; each call replaces the previous report. Getters then answer with the value you set, or failing that the reported one. Reported values are never sent back when the object is passed to `launch` or `relaunch`. + +```ts +import Bugsee, { BugseeLaunchOptions, createDefaultLaunchOptions } from '@bugsee/react-native'; + +async function effectiveDuration() { + const options = createDefaultLaunchOptions(); + BugseeLaunchOptions.refreshFrom(options, await Bugsee.getLaunchOptions()); + return options.duration; // the duration in effect +} +``` + +## Changing options at runtime + +Options apply when the SDK launches. To change them later, pass a new set to `Bugsee.relaunch(options)`, which restarts the session; see [Lifecycle & status](/sdk/react_native/lifecycle). + +## Worked example + +```ts +import { Platform } from 'react-native'; +import Bugsee, { + AndroidLaunchOptions, + CrashHandlerType, + IOSLaunchOptions, + IssueSeverity, + LogLevel, + createDefaultLaunchOptions, +} from '@bugsee/react-native'; + +const options = createDefaultLaunchOptions(); +options.duration = 90; +options.captureBreadcrumbs = true; +options.captureLogsLevel = LogLevel.Info; +options.detectAndReportHang = true; +options.setCustomOption('com.bugsee.option.reporting.triggers.shake', false); +options.setCustomOption('com.bugsee.option.reporting.defaults.bug-priority', IssueSeverity.Medium); + +if (options instanceof AndroidLaunchOptions) { + options.triggerByNotification = false; +} else if (options instanceof IOSLaunchOptions) { + options.crashHandlerType = CrashHandlerType.MachAndBSD; +} + +Bugsee.launch( + Platform.OS === 'ios' ? '' : '', + options, +); +``` + +## Related pages + +- [Installation](/sdk/react_native/installation): launching the SDK. +- [Lifecycle & status](/sdk/react_native/lifecycle): `relaunch` with new options. +- [Privacy](/sdk/react_native/privacy/overview): masking and filters. +- Native SDK reference: [Android configuration](/sdk/android/configuration) and [iOS configuration](/sdk/ios/configuration#available-options) (6.x option names; the [iOS 7.x migration guide](/sdk/ios/v7/migration#2-option-keys) maps them to the 7.x keys). diff --git a/sidebars.ts b/sidebars.ts index 4085e0f..6bf7526 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -573,6 +573,11 @@ const sidebars: SidebarsConfig = { }, ], }, + { + type: "doc", + id: "sdk/react_native/configuration", + label: "Configuration", + }, { type: "category", label: "Previous versions", From a5dc28e09e838b78813f62b7a4b23e2fb7adb6fb Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 22:56:50 +0500 Subject: [PATCH 07/49] docs(react-native): Lifecycle & status (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit launch, relaunch, stop and attach with what each resolves to, what launch sets up, pre-launch behaviour, getStatus and Status, onStatusChange, onLifecycleEvent and the event list, and blackout. Verified against packages/react-native/src/ index.ts, status.ts, wrapper/events.ts, wrapper/lifecycle-events.ts and the native BugseeModule launch/stop/status paths on both platforms. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ieaa74605603726ad57005ff6da29fbd93f4ad603 --- docs/sdk/react_native/lifecycle.mdx | 208 ++++++++++++++++++++++++++++ sidebars.ts | 5 + 2 files changed, 213 insertions(+) create mode 100644 docs/sdk/react_native/lifecycle.mdx diff --git a/docs/sdk/react_native/lifecycle.mdx b/docs/sdk/react_native/lifecycle.mdx new file mode 100644 index 0000000..0a42e82 --- /dev/null +++ b/docs/sdk/react_native/lifecycle.mdx @@ -0,0 +1,208 @@ +--- +title: "Lifecycle & status" +description: "Launching, stopping, relaunching and attaching to Bugsee React Native SDK 7.x, reading its status, and subscribing to its lifecycle events." +sidebar_position: 4 +slug: "/sdk/react_native/lifecycle" +--- + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +The SDK can be launched, stopped and relaunched at runtime. You can ask for its current status at any time, and subscribe to its lifecycle events: status transitions, report assembly and upload, blackouts and crash relaunches. + +## Launch, stop, and relaunch + +Each call returns a promise that settles once the native SDK has answered. + +```ts +import Bugsee, { createDefaultLaunchOptions } from '@bugsee/react-native'; + +async function start(): Promise { + return Bugsee.launch('', createDefaultLaunchOptions()); +} + +async function shutDown(): Promise { + await Bugsee.stop(); +} + +// Relaunch with a new set of options (no token: the session's own is kept) +async function restartWithoutVideo(): Promise { + const options = createDefaultLaunchOptions(); + options.captureVideo = false; + return Bugsee.relaunch(options); +} +``` + +| Method | Resolves to | Notes | +| --- | --- | --- | +| `launch(token, options?)` | `boolean` | `true` when the SDK started, and also when it was already running or launching: that second launch does not apply its options (see [Launching again](#launching-again)). `false` when it declined, for example because the backend rejected the token. A missing or blank token rejects with `code` `E_TOKEN`. | +| `relaunch(options?)` | `boolean` | Restarts an already-launched session with a new set of options. `true` when the SDK restarted, on both platforms. | +| `stop()` | `boolean` | Resolves `true` once the native SDK has stopped; it never resolves `false`. | +| `attach()` | `void` | Wires up the JavaScript layer when the native SDK was launched without JavaScript. See [Attach to a running SDK](#attach-to-a-running-sdk). | + +`launch` and `relaunch` take the options object or a plain `com.bugsee.option.*` map; see [Configuration](/sdk/react_native/configuration). Declining is a normal outcome rather than an error, so `launch` does not reject when the SDK declines. + +### What `launch` sets up + +Besides starting the native SDK, `launch` (and `relaunch`) prepare the JavaScript side: + +1. Identifies the app to the SDK as a React Native app before launching, so a report produced during startup says it came from React Native. +2. Installs the global JavaScript exception handlers, for uncaught errors (`ErrorUtils`) and unhandled promise rejections. `detectAndReportCrash: false` (`com.bugsee.option.detect.crash`) turns their reporting off. +3. Launches the native SDK. +4. Once the native call resolves, patches `console.*` so each line still prints and is also forwarded to Bugsee. A rejected launch does not install the patch. A later call does not wrap the functions again, but re-reads `com.bugsee.option.capture.logs`, so a relaunch can turn console forwarding off or on. + +Both settings follow the options passed to each call, not the options in effect. A `relaunch(options)` whose options leave out `com.bugsee.option.capture.logs` turns console forwarding back on, and one that leaves out `com.bugsee.option.detect.crash` turns JavaScript exception reporting back on, even if an earlier call set them to `false`. + +:::caution[Hermes promise rejection tracker] +On Hermes, the last caller of `enablePromiseRejectionTracker` wins, and Hermes has no way to read the current tracker. Another library that installs a tracker after `Bugsee.launch` replaces Bugsee's, and unhandled promise rejections are then no longer reported. +::: + +### Launching again + +A `launch` while the SDK is already running or launching starts nothing and resolves `true`, on both platforms. The options it carries are **not applied**: the session keeps the options it started with, and on Android, a call that carried options logs a warning to logcat. The JavaScript side still follows the new options, though (see [What `launch` sets up](#what-launch-sets-up)), so the two can disagree. To change options, call `relaunch(options)` instead. + +A `launch` made while the SDK is still stopping differs per platform. Android: it resolves `false` and does not launch. iOS: it resolves `true`, but does not launch either. Launch again once `stop()` has resolved. + +### A resolved launch is not live capture + +When `launch` resolves `true`, the SDK has started, but how far it has got differs per platform: + +- **Android**: `launch` resolves once capture is up. The status is already `Launched`. The exception is a `launch` that joins one already in progress, which resolves at once. +- **iOS**: `launch` resolves while the status is still `Launching`, and recording may not have begun yet. A `launch` made while the app is in the background resolves `true` too, and the SDK starts when the app becomes active. + +Check [the status](#querying-status) or wait for the `Launched` event rather than assuming. + +On iOS, a report-creating call made while the status is still `Launching` would be dropped. The SDK works around this: `Bugsee.logException`, `Bugsee.upload`, `Bugsee.createReport` and `Bugsee.showReportDialog` calls made while the status is `Launching` are held, then replayed in order once it is `Launched`. They are dropped instead if the SDK reports `Stopping` or `Stopped`, if 30 seconds pass without `Launched`, or if 64 calls are already held. A call made while nothing is held runs at once. + +## Before launch + +Most calls need a launched SDK. Before `launch`: + +- `Bugsee.upload` and `Bugsee.showReportDialog` do nothing, and `Bugsee.createReport` resolves `null`. +- `Bugsee.log` lines, `Bugsee.logException` errors and `Bugsee.notify` items are dropped. +- `Bugsee.startBlackout()` is honored on both platforms: call it before `launch` to keep the first seconds of a session hidden from the video. See [Privacy: Video](/sdk/react_native/privacy/video). + +:::tip[Install the report handler first] +Call `Bugsee.setReportHandler` **before** `Bugsee.launch`. During launch the SDK recovers reports from the previous run, such as a crash, and a handler installed afterward misses them. See [Report handler](/sdk/react_native/report-handler). +::: + +## Attach to a running SDK + +The native SDK can be launched before any JavaScript runs: + +- **Android**: the native SDK can launch itself at process start from the `com.bugsee.app-token` manifest meta-data. The [Expo config plugin](/sdk/react_native/expo#auto-launch-on-android) writes it with `autoLaunch: true`. +- **iOS**: there is no auto-launch, but your app can launch the SDK from its own native code, for example in its `AppDelegate`. + +In that case, call `Bugsee.attach()` instead of `launch`. It makes no launch call, and only sets up the JavaScript side: + +```ts +import Bugsee from '@bugsee/react-native'; + +Bugsee.attach(); +``` + +A `launch` would not start a second session either, but it would not apply its options, while the JavaScript side applied them; see [Launching again](#launching-again). `attach` instead reads the options the SDK is running with, and applies `com.bugsee.option.detect.crash` from them before it installs the exception handlers. Exception capture is held off while it reads, so an error raised in that gap is not reported, rather than being reported when the option turns out to be `false`. It then installs the console patch from the same options. If reading the options fails, the promise rejects, and neither the handlers nor the console patch are installed. + +`attach` works the same on both platforms. On iOS, attaching to an SDK your native code launched has not been verified on a device in this beta. + +A report the SDK produces before JavaScript runs (such as a crash recovered from the previous run) is attributed to React Native on Android, where the package identifies itself at process start. On iOS the package does that when React Native loads it, so a report produced before then may not be. + +Reports carry the React Native SDK type and version but not the JavaScript details (React Native version, JavaScript engine, development build): `attach()` does not register them. Only `launch` and `relaunch` do, so a `relaunch` after `attach()` adds them for the rest of the session. A `relaunch(options)` is also the way to apply launch options from JavaScript, since the SDK started with the options of the manifest (Android) or of your native code (iOS). + +## Querying status + +`Bugsee.getStatus()` resolves to the SDK's current status, a `Status` value: + +| `Status` | Value | Meaning | +| --- | --- | --- | +| `Stopped` | `0` | Not running. Also reported when the SDK was never launched. | +| `Launching` | `1` | Starting up. | +| `Launched` | `2` | Running. | +| `Stopping` | `3` | Shutting down. | + +```ts +import Bugsee, { Status } from '@bugsee/react-native'; + +async function isRunning(): Promise { + return (await Bugsee.getStatus()) === Status.Launched; +} +``` + +A status value this version of the SDK does not recognize, from a newer native SDK, is reported as `Stopped` rather than passed through. + +### Status changes + +`Bugsee.onStatusChange(listener)` calls `listener` with the new `Status` on each transition, and returns a subscription with `remove()`: + +```ts +import Bugsee, { Status } from '@bugsee/react-native'; + +const subscription = Bugsee.onStatusChange((status) => { + if (status === Status.Launched) { + // Capture is up. + } +}); + +// Later +subscription.remove(); +``` + +Status changes are derived from the lifecycle events: the `Launching`, `Launched`, `Stopping` and `Stopped` events each produce one call, and no other event does. + +## Lifecycle events + +`Bugsee.onLifecycleEvent(listener)` subscribes to every lifecycle event the SDK dispatches, and returns a subscription with `remove()`. Each event is a `LifecycleEvent`: + +```ts +interface LifecycleEvent { + name: string; // for example 'RelaunchedAfterCrash' + reportId?: string; // only on the events that carry one +} +``` + +```ts +import Bugsee from '@bugsee/react-native'; + +const subscription = Bugsee.onLifecycleEvent((event) => { + if (event.name === 'RelaunchedAfterCrash') { + // The previous session ended with a crash. + } + if (event.name === 'AfterReportUploaded') { + console.log('uploaded report', event.reportId); + } +}); + +// Unsubscribe +subscription.remove(); +``` + +Both platforms dispatch these events, by the same names: + +| Event | `reportId` | Description | +| --- | --- | --- | +| `Launching` / `Launched` | no | The SDK is starting / has started. | +| `Stopping` / `Stopped` | no | The SDK is stopping / has stopped. | +| `BlackoutStarted` / `BlackoutEnded` | no | Visual capture paused / resumed by `startBlackout()` / `endBlackout()`. | +| `RelaunchedAfterCrash` | no | The SDK launched and found a crash from the previous session. | +| `BeforeReportShown` / `AfterReportShown` | no | The report UI is about to be / has been shown. No report exists yet at this point. | +| `BeforeReportAssembled` / `AfterReportAssembled` / `ReportAssemblyFailed` | yes | Report assembly stages. | +| `BeforeReportUploaded` / `AfterReportUploaded` | yes | Report upload start / success. | +| `ReportUploadFailedWithFutureRetry` / `ReportUploadFailed` | yes | Upload failed, to be retried / permanently. | + +How events are delivered: + +- They arrive off the main thread on both platforms and reach JavaScript as they come. +- Nothing is queued while there is no subscriber, so a subscription made after launch does not replay what it missed. Ask `getStatus()` for the current state rather than rebuilding it from events. +- An event this version of the SDK does not know is delivered unchanged rather than dropped, so a newer native SDK can reach your listener. Compare `name` against the names you handle and ignore the rest. + +## Blackout + +`Bugsee.startBlackout()` and `Bugsee.endBlackout()` bracket a window in which everything that describes the screen is suppressed (the video, the report screenshot, touches and the view hierarchy), while logs, network events, custom events and traces keep recording. `Bugsee.isBlackout()` resolves to the current state. Use a blackout to hide a sensitive flow without stopping the SDK; see [Privacy: Video](/sdk/react_native/privacy/video). To shut the SDK down, use `stop()`. + +## Related pages + +- [Installation](/sdk/react_native/installation): the first launch. +- [Configuration](/sdk/react_native/configuration): the options `launch` and `relaunch` take. +- [Expo](/sdk/react_native/expo): Android auto-launch with the config plugin. +- [Report handler](/sdk/react_native/report-handler): changing reports before they are sent. diff --git a/sidebars.ts b/sidebars.ts index 6bf7526..b6a6373 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -578,6 +578,11 @@ const sidebars: SidebarsConfig = { id: "sdk/react_native/configuration", label: "Configuration", }, + { + type: "doc", + id: "sdk/react_native/lifecycle", + label: "Lifecycle & status", + }, { type: "category", label: "Previous versions", From bd1cff4884fb42786d5a8a20c20da4edb7cceb96 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 23:12:54 +0500 Subject: [PATCH 08/49] docs(react-native): Bug reporting (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Report triggers, showReportDialog and upload with their argument checks and defaults, createReport and the created-report API (one at a time, upload results, platform limits), pre-launch behaviour, errors and default severities. Verified against src/index.ts, src/report/{fields,CreatedReport,errors,types}.ts and the native upload/showReportDialog/createReport paths in BugseeModule. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ia4fcb28ccdef952d4e733a308823ae40406b75e5 --- .../sdk/react_native/manual/bug-reporting.mdx | 237 ++++++++++++++++++ sidebars.ts | 12 + 2 files changed, 249 insertions(+) create mode 100644 docs/sdk/react_native/manual/bug-reporting.mdx diff --git a/docs/sdk/react_native/manual/bug-reporting.mdx b/docs/sdk/react_native/manual/bug-reporting.mdx new file mode 100644 index 0000000..fcfff17 --- /dev/null +++ b/docs/sdk/react_native/manual/bug-reporting.mdx @@ -0,0 +1,237 @@ +--- +title: "Bug reporting" +description: "Let users and your code file bug reports with Bugsee React Native SDK 7.x: the built-in triggers, the report dialog, silent upload, and building a report with createReport." +sidebar_position: 1 +slug: "/sdk/react_native/manual/bug-reporting" +--- + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +Bug reports cover something that is wrong but did not crash the app. Your users can raise one with a gesture, or you can open the report dialog, or submit a report silently, from your own code. Crashes and handled errors are covered separately, in [Crash & error reporting](/sdk/react_native/manual/crash-error-reporting). + +All three calls on this page need a launched SDK; see [Before launch](#before-launch). + +## Built-in report triggers + +The native SDKs can open the report dialog on their own, without any call from your code. These triggers are launch options: + +| Key | Accessor | Platforms | Default | Opens the report dialog when | +| --- | --- | --- | --- | --- | +| `com.bugsee.option.reporting.triggers.shake` | none | both | `true` | The user shakes the device. | +| `com.bugsee.option.reporting.triggers.screenshot` | none | both | `false` | The user takes a screenshot. | +| `com.bugsee.option.reporting.triggers.notification-bar` | `triggerByNotification` | Android | `true` | The user taps the Bugsee entry in the notification bar. | +| `com.bugsee.option.reporting.triggers.broadcast` | none | Android | `false` | An Android broadcast intent asks for a report. | + +Turn the shake trigger off, and the screenshot trigger on, at launch: + +```ts +import Bugsee, { AndroidLaunchOptions, createDefaultLaunchOptions } from '@bugsee/react-native'; + +const options = createDefaultLaunchOptions(); +options.setCustomOption('com.bugsee.option.reporting.triggers.shake', false); +options.setCustomOption('com.bugsee.option.reporting.triggers.screenshot', true); +if (options instanceof AndroidLaunchOptions) { + options.triggerByNotification = false; +} + +Bugsee.launch('', options); +``` + +The Android-only keys are not recognized on iOS, so set them only on an Android options object. The options that shape the dialog itself (required fields, the labels field, the priority selector) are listed under [Configuration: Reporting](/sdk/react_native/configuration#reporting). + +## Show the report dialog + +`Bugsee.showReportDialog(summary?, description?, severity?, labels?)` opens the standard reporting UI. Every argument is optional and only pre-fills the form: the user can still edit the values before sending. + +```ts +import Bugsee, { IssueSeverity } from '@bugsee/react-native'; + +// An empty form +Bugsee.showReportDialog(); + +// Pre-fill the summary and description +Bugsee.showReportDialog('Checkout is frozen', 'The spinner never stops.'); + +// Pre-fill everything, including severity and labels +Bugsee.showReportDialog( + 'Checkout is frozen', + 'The spinner never stops.', + IssueSeverity.High, + ['checkout'], +); + +// Severity only: leave the text fields out with undefined +Bugsee.showReportDialog(undefined, undefined, IssueSeverity.Critical); +``` + +| Argument | Type | When omitted | +| --- | --- | --- | +| `summary` | `string` | The field is left empty. | +| `description` | `string` | The field is left empty. | +| `severity` | `IssueSeverity` | The SDK's default bug severity. | +| `labels` | `readonly string[]` | No labels are pre-filled. | + +The call returns nothing (`void`) and does not tell you whether the user sent the report or dismissed the dialog. Subscribe to the `BeforeReportShown`, `AfterReportShown` and upload [lifecycle events](/sdk/react_native/lifecycle#lifecycle-events) to follow it. + +The dialog runs your report handler's `onBeforeReportCreated` before it opens; see [Report handler](/sdk/react_native/report-handler). + +## Silent upload + +`Bugsee.upload(summary, description, severity?, labels?)` creates a bug report and uploads it at once, without any UI. Use it when you have already collected the details in your own UI. + +```ts +import Bugsee, { IssueSeverity } from '@bugsee/react-native'; + +Bugsee.upload('Checkout frozen', 'Spinner never stops'); + +Bugsee.upload('Checkout frozen', 'Spinner never stops', IssueSeverity.High, ['checkout']); +``` + +`summary` and `description` are required, and both must be strings; an empty string is accepted. An omitted `severity` gets the default bug severity, `com.bugsee.option.reporting.defaults.bug-priority` (`High` unless you set it), on both platforms. An omitted `labels` sends no labels. + +Like `showReportDialog`, `upload` returns `void`. Follow the upload with the `BeforeReportUploaded`, `AfterReportUploaded` and `ReportUploadFailed*` [lifecycle events](/sdk/react_native/lifecycle#lifecycle-events). + +:::warning +Do not call `upload` from automated error paths. To report an error from code, use [`Bugsee.logException`](/sdk/react_native/manual/crash-error-reporting#reporting-handled-errors): an error report carries the stack trace and is grouped with the other occurrences of the same error. +::: + +### Argument checks + +`upload` and `showReportDialog` check their arguments in JavaScript and throw synchronously, before anything reaches the native SDK: + +| Argument | Rule | Thrown | +| --- | --- | --- | +| `summary`, `description` | A string (required for `upload`, optional for `showReportDialog`). | `TypeError` | +| `severity` | Omitted, or an integer from `1` to `5` (an `IssueSeverity` value). | `TypeError` for a non-number, `RangeError` for any other number | +| `labels` | Omitted, or an array of strings. The array is copied. | `TypeError` | +| a fifth argument | `upload` takes at most four arguments. 7.x has no `includeVideo`. | `TypeError` | + +`labels` is still an argument of both calls; only `Bugsee.logException` lost its per-call labels in 7.x (see [Crash & error reporting](/sdk/react_native/manual/crash-error-reporting#reporting-handled-errors)). + +## Build a report yourself + +When you need to fill a report over time, attach files to it, or decide when it is sent, use `Bugsee.createReport()`. It resolves to a `BugseeCreatedReport` that you fill and then send with its own `upload()`: + +```ts +import Bugsee, { IssueSeverity } from '@bugsee/react-native'; + +// React Native's default TypeScript config has no DOM types, so declare the +// global btoa the runtime provides (or use a base64 library). +declare function btoa(data: string): string; + +async function reportCheckoutProblem(logText: string): Promise { + const report = await Bugsee.createReport(); + if (report === null) { + return; // The SDK made no report: it is not launched. + } + await report.update({ + summary: 'Checkout frozen', + description: 'The spinner never stops.', + severity: IssueSeverity.High, + labels: ['checkout'], + attributes: { cartSize: 3 }, + }); + await report.addDataAttachment(btoa(logText), { + name: 'checkout.log', + mimeType: 'text/plain', + }); + const uploaded = await report.upload(); + console.log('report handed off:', uploaded); +} +``` + +`btoa` encodes only Latin-1 text; encode other text to bytes first, or use a base64 library. + +`createReport()` resolves `null` when the SDK made no report, for example before `launch`. The created report has these methods, each returning a promise: + +| Method | Resolves to | Description | +| --- | --- | --- | +| `read()` | `BugseeReportSnapshot` | The report's current fields; see [The snapshot](/sdk/react_native/report-handler#reading-a-report). | +| `update(patch)` | `void` | Changes summary, description, severity, labels and attributes in one call; see [Changing a report](/sdk/react_native/report-handler#changing-a-report). | +| `addFileAttachment(path, { name, mimeType? })` | `void` | Attaches a file. The file is copied when it is added; there is no `move` option on a created report. | +| `addDataAttachment(base64, { name, mimeType? })` | `void` | Attaches bytes, given as a base64 string. | +| `upload()` | `boolean` | Hands the report to the SDK for upload. | + +The patch, the snapshot and the attachment arguments are the same as on a [report handler](/sdk/react_native/report-handler)'s report, which has the details. A created report has no `id`, no `type` and no deadline: it stays open until you upload it. + +### One created report at a time + +Only one created report can be outstanding. A second `createReport()` before the first is uploaded rejects with a `BugseeReportError` whose `code` is `E_REPORT_CREATE_BUSY`. There is no call that discards a created report, so always finish one with `upload()`; the slot is otherwise freed only when the JavaScript runtime reloads. On iOS the slot stays taken until that upload has completed, so a `createReport()` made while the previous upload is still in progress also rejects. + +`upload()` ends the report. Every later call on it, including a second `upload()`, rejects with `E_REPORT_HANDLE_DEAD`, whatever the upload's result was. Call `createReport()` again for another report. + +What `upload()` resolves to differs by platform: + +- **Android**: the result the SDK reports for the upload. +- **iOS**: always `true`, once the report is handed off, even when the SDK is not launched. It does not tell you whether the upload succeeded. + +### Platform differences + +| | Android | iOS | +| --- | --- | --- | +| Attachments on a created report | Up to 1000. | At most 3, each non-empty and at most 3 MiB. A further or larger one rejects with `E_REPORT_ATTACHMENT_REJECTED`. `mimeType` is ignored. | +| When the report handler runs | `onBeforeReportCreated` runs inside `createReport()`, `onAfterReportCreated` at `upload()`. | Both callbacks run at `upload()`, after the created report's fields are copied, so a handler's `setLabels` replaces the labels you set. | + +## Before launch + +Before `launch`, `upload` and `showReportDialog` do nothing, and `createReport()` resolves `null`. Nothing is queued for later. + +On iOS, a call made while the SDK is still starting (status `Launching`) is held and replayed once it is `Launched`; see [A resolved launch is not live capture](/sdk/react_native/lifecycle#a-resolved-launch-is-not-live-capture). + +## Errors + +Created-report operations reject with a `BugseeReportError` for the codes below; match on its `code`, a `ReportErrorCode` value. Any other failure, such as an unexpected native fault, rejects with an ordinary error, so rethrow what you do not match. + +| `ReportErrorCode` | `code` | Meaning | +| --- | --- | --- | +| `CreateBusy` | `E_REPORT_CREATE_BUSY` | Another created report is still outstanding. | +| `HandleDead` | `E_REPORT_HANDLE_DEAD` | The report was already uploaded. | +| `AttachmentRejected` | `E_REPORT_ATTACHMENT_REJECTED` | The attachment was declined. | +| `BadArgument` | `E_REPORT_BAD_ARGUMENT` | An argument failed validation; nothing was sent. | + +```ts +import Bugsee, { BugseeReportError, ReportErrorCode } from '@bugsee/react-native'; + +async function openReport() { + try { + return await Bugsee.createReport(); + } catch (error) { + if (error instanceof BugseeReportError && error.code === ReportErrorCode.CreateBusy) { + return null; // Finish the outstanding report first. + } + throw error; + } +} +``` + +## Default severities + +A report gets a default severity unless one is passed or set from a report handler. Change the defaults with these launch options: + +| Key | Default | Applies to | +| --- | --- | --- | +| `com.bugsee.option.reporting.defaults.crash-priority` | `IssueSeverity.Blocker` | Crash reports | +| `com.bugsee.option.reporting.defaults.error-priority` | `IssueSeverity.High` | Error reports | +| `com.bugsee.option.reporting.defaults.bug-priority` | `IssueSeverity.High` | Bug reports | + +```ts +import Bugsee, { IssueSeverity, createDefaultLaunchOptions } from '@bugsee/react-native'; + +const options = createDefaultLaunchOptions(); +options.setCustomOption('com.bugsee.option.reporting.defaults.bug-priority', IssueSeverity.Medium); + +Bugsee.launch('', options); +``` + +## Severity values + +`IssueSeverity` values: `VeryLow` (1), `Medium` (2), `High` (3), `Critical` (4), `Blocker` (5). Pass the constants rather than numbers; see the [enum reference](/sdk/react_native/configuration#enum-reference). + +## Related pages + +- [Crash & error reporting](/sdk/react_native/manual/crash-error-reporting): handled errors and crashes. +- [Report handler](/sdk/react_native/report-handler): change every report before it is sent. +- [Lifecycle & status](/sdk/react_native/lifecycle): the report events. +- [Feedback](/sdk/react_native/feedback): the in-app feedback chat. diff --git a/sidebars.ts b/sidebars.ts index b6a6373..29da66a 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -583,6 +583,18 @@ const sidebars: SidebarsConfig = { id: "sdk/react_native/lifecycle", label: "Lifecycle & status", }, + { + type: "category", + label: "Manual reporting", + collapsed: true, + items: [ + { + type: "doc", + id: "sdk/react_native/manual/bug-reporting", + label: "Bug reporting", + }, + ], + }, { type: "category", label: "Previous versions", From e8f147269d1cc3b655dd92e6afdfc2d2e5fe8d93 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 23:14:12 +0500 Subject: [PATCH 09/49] docs(react-native): Crash & error reporting (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What is reported automatically and as what (fatal/non-fatal JS errors, unhandled rejections as errors, render errors via Bugsee.wrap, native crashes), the detect.crash switch, logException with { domain }, logUnhandledException, dedup, AggregateError, payload contents and the test helpers. Verified against src/index.ts and src/exceptions/{handlers,report,options,payload,RootErrorReporter}.ts(x). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ice0cecd8c74249a5ad6287507dcf69c94dd99cb2 --- .../manual/crash-error-reporting.mdx | 197 ++++++++++++++++++ sidebars.ts | 5 + 2 files changed, 202 insertions(+) create mode 100644 docs/sdk/react_native/manual/crash-error-reporting.mdx diff --git a/docs/sdk/react_native/manual/crash-error-reporting.mdx b/docs/sdk/react_native/manual/crash-error-reporting.mdx new file mode 100644 index 0000000..5fe01b7 --- /dev/null +++ b/docs/sdk/react_native/manual/crash-error-reporting.mdx @@ -0,0 +1,197 @@ +--- +title: "Crash & error reporting" +description: "What Bugsee React Native SDK 7.x reports automatically (JavaScript errors, unhandled promise rejections, render errors, native crashes), and how to report handled and unhandled errors yourself." +sidebar_position: 2 +slug: "/sdk/react_native/manual/crash-error-reporting" +--- + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +Most crashes and errors are reported **automatically** once `Bugsee.launch` has run: you do not need to call anything. This page lists what is captured and how each kind is reported, then covers the cases where you report something yourself: handled errors, errors your app treats as crashes, and checking that the pipeline works. + +Bugsee files two kinds of report here: + +- a **crash** report, for something that ended (or is about to end) the app, with the default severity `Blocker`; +- an **error** report, for a handled, non-terminal error, with the default severity `High`. + +Release builds need source maps and native symbols uploaded for their stack traces to resolve to your source; see [Symbolication](/sdk/react_native/symbolication/overview). + +## What is captured automatically + +| Source | Reported as | Needs | +| --- | --- | --- | +| Uncaught JavaScript error that React Native reports as fatal | crash | `launch` | +| JavaScript error reported to the global handler as non-fatal | error | `launch` | +| Unhandled promise rejection | **error** | `launch` | +| Uncaught render error (no error boundary catches it) | crash | [`Bugsee.wrap`](/sdk/react_native/installation#4-launch-bugsee) around your root component | +| Render error caught by Bugsee's `` | error | [``](/sdk/react_native/error-boundary) | +| Native crash | crash | `launch` | + +### JavaScript errors + +`Bugsee.launch` (and `relaunch`, and `attach`) installs a global error handler through React Native's `ErrorUtils`. The handler keeps the one that was installed before it and always calls it afterward, so React Native's own handling (the red error screen in a development build) still runs. + +- A **fatal** error is reported as a crash. The handler waits until the native SDK has taken the report, at most 1.5 seconds on iOS and 5 seconds on Android, and only then passes the error on, so the report is stored before the app goes down. +- A **non-fatal** error is reported as an error, and passed on at once. + +### Unhandled promise rejections + +`launch` also installs a promise rejection tracker. An unhandled rejection is reported as an **error** report, not a crash, because it does not stop the app. In a development build, React Native's own warning for the rejection still appears. + +:::caution +On Hermes, the last library to install a promise rejection tracker wins. Another library that installs one after `Bugsee.launch` replaces Bugsee's, and unhandled rejections are then no longer reported; see [Lifecycle & status](/sdk/react_native/lifecycle#what-launch-sets-up). +::: + +### Render errors + +In React Native 0.81 and later (the minimum this SDK supports), an error thrown while rendering a component never passes through `ErrorUtils`: React hands it to React Native directly. The global handler above therefore does not see it. + +- **Uncaught render errors** are reported by `Bugsee.wrap`. It renders your root component inside a reporter that reports the error as a crash, renders nothing while the report is stored, then throws the same error again so React Native's fatal path still runs. Without `Bugsee.wrap`, an uncaught render error is not reported. +- **Render errors you catch** with an error boundary are reported only by Bugsee's own [``](/sdk/react_native/error-boundary), as errors. An error boundary from React or another library catches the error before Bugsee sees it; call [`Bugsee.logException`](#reporting-handled-errors) from its `componentDidCatch` if you keep it. + +### Native crashes + +Crashes in native code are captured too: + +- **Android**: uncaught exceptions in Java and Kotlin code, and crashes in native (NDK) code. +- **iOS**: uncaught Objective-C exceptions (`NSException`), and fatal signals (`SIGABRT`, `SIGSEGV`, `SIGBUS`, `SIGILL`, `SIGFPE` and `SIGTRAP`, which includes Swift runtime traps), whether raised by a hardware fault or by software (with the default `crashHandlerType`). + +On iOS, `crashHandlerType` and `crashSignals` choose how crashes are intercepted; see [iOS accessors](/sdk/react_native/configuration#ios-accessors). Other detectors (hangs, low-memory exits, HTTP errors) are launch options too; see [Detection](/sdk/react_native/configuration#detection). + +:::caution[iOS Simulator] +In this beta, the iOS Simulator produces no crash reports: neither native crashes nor JavaScript crashes. Test crash reporting on a physical iPhone. +::: + +:::caution[iOS: Xcode debugger and TestFlight] +- **Debugger.** When the SDK launches while the Xcode debugger is attached, it does not intercept crashes for that session, and the debugger handles them instead. To test crash reporting, start the app from the device's home screen, not from Xcode. +- **TestFlight.** In builds installed through TestFlight, the system can intercept crashes before Bugsee does. On test devices, turn off **Share With App Developers** in *Settings > Privacy & Security > Analytics & Improvements*. See the iOS [TestFlight builds](/sdk/ios/v7/installation#testflight-builds) notes. +::: + +### Turning automatic reporting off + +`detectAndReportCrash: false` (`com.bugsee.option.detect.crash`) turns off native crash reporting, and also the reporting of uncaught JavaScript errors, unhandled promise rejections and uncaught render errors. The handlers stay installed and keep passing errors on; they just report nothing. + +It does not turn off what you report on purpose: `Bugsee.logException` and `` still report, and so does `Bugsee.logUnhandledException` (verified on Android; on iOS, where the crash is recovered at the next launch, this is not verified in this beta). + +The setting follows the options of each `launch` or `relaunch` call; see [What launch sets up](/sdk/react_native/lifecycle#what-launch-sets-up). + +## Reporting handled errors + +`Bugsee.logException(error, options?)` records a caught error as an **error** report, without crashing the app: + +```ts +import Bugsee from '@bugsee/react-native'; + +async function loadProfile(): Promise { + try { + await fetchProfile(); + } catch (error) { + Bugsee.logException(error); + showOfflineBanner(); + } +} +``` + +`error` can be any value. An `Error` (or a subclass) gives the best report: its name, message, stack and `cause` chain. For any other value, see [What a report carries](#what-a-report-carries). + +`logException` returns `void`. Before `launch` the native SDKs drop the error; on iOS, one logged while the SDK is still starting is held until it has launched (see [Lifecycle & status](/sdk/react_native/lifecycle#a-resolved-launch-is-not-live-capture)). + +### Options + +`options` is an `ExceptionOptions` object with one key: + +| Key | Type | Description | +| --- | --- | --- | +| `domain` | `string` | The exception domain. Android groups issues by it; iOS records it with the report. Non-empty, at most 256 characters. | + +```ts +Bugsee.logException(error, { domain: 'checkout' }); +``` + +The options are checked before anything is sent, and a bad option throws synchronously: a `TypeError` for an options value that is not a plain object, an unknown key or a non-string `domain`, and a `RangeError` for an empty `domain` or one over 256 characters. + +:::note[No per-call labels or `includeVideo`] +In 7.x, `logException` takes `{ domain }` only, as the 7.x native SDKs do. `labels` and `includeVideo` throw `TypeError: ExceptionOptions has unknown key "labels"` (or `"includeVideo"`). + +Set labels from a [report handler](/sdk/react_native/report-handler) instead. A handler has no per-call context, so the labels it sets apply to every report it handles; check `report.type` to limit them to error reports. `includeVideo` has no replacement: neither SDK can leave the video out of one report. (`Bugsee.upload` and `Bugsee.showReportDialog` still take `labels`.) +::: + +:::warning +Do not call `Bugsee.upload` from automated error paths. Use `logException`, so the report carries the stack trace and is grouped with the other occurrences of the same error. +::: + +## Reporting unhandled errors + +`Bugsee.logUnhandledException(error)` reports `error` as a **crash**. Use it for an error your app treats as fatal but that Bugsee's handlers did not see, for example because another error handler takes it first: + +```ts +import Bugsee from '@bugsee/react-native'; + +async function onFatalError(error: unknown): Promise { + await Bugsee.logUnhandledException(error); + // Now end the session your own way. +} +``` + +It returns a promise that resolves once the native SDK has the report, after at most 1.5 seconds on iOS and 5 seconds on Android. It never rejects. Await it before the app goes down, so the report is stored first. + +On iOS, the crash report is stored and sent at the next launch, as for any crash. + +For a handled, non-terminal error, use [`logException`](#reporting-handled-errors) instead. Automatic capture does not need either call. + +## Each error is reported once + +Bugsee remembers every error **object** it has reported, and does not report the same object again, whichever route sees it second: `logException`, `logUnhandledException`, the global handler, the rejection tracker, `` or `Bugsee.wrap`. An error that more than one route sees produces one report from the JavaScript layer. + +Two consequences: + +- If you log an error and then rethrow it, the rethrown error is not reported again, not even as a crash. If the error is going to end the app, report it with `logUnhandledException` instead of `logException`, not after it: whichever call sees the error object first claims it, and later calls for the same object do nothing. +- An error object is claimed even when its report is dropped. `logException` before `launch` claims the object although the native SDK drops the report, so no later route reports that same object. +- A primitive (a thrown string or number) cannot be remembered, so the same string logged twice produces two reports. + +### `AggregateError` + +A handled `AggregateError` is split: each of its first 10 inner errors becomes its own error report, and the aggregate itself is not reported. Inner errors already reported are skipped. An unhandled `AggregateError` (from `logUnhandledException` or a fatal error) stays one crash report. + +## What a report carries + +The exception is built from the JavaScript error, the same way on both platforms: + +- **Name and message.** For an `Error`, its `name` and `message`. A thrown string becomes the message, with the name `Error`. An object with a string `message` gives that message (and its `name`, when that is a string). Anything else is reported as `Non-Error thrown: `. +- **Stack trace.** The error's own stack, up to 256 frames. A value that is not an `Error` has no stack of its own, so `logException` and `logUnhandledException` record the stack at the point you called them. +- **Causes.** The `cause` chain, up to 10 levels deep. +- **Component stack.** For a render error, the React component stack, as the innermost cause. + +The message is cut at 8192 characters and the name at 256; a cut value ends in `…`. + +## Testing crash reporting + +Two helpers check that reporting is wired up. Use them only in development and QA builds. + +```ts +import Bugsee from '@bugsee/react-native'; + +// Throws an Error('Bugsee test JS crash') at the call site. +Bugsee.testJsCrash(); + +// Raises a native test crash, which ends the app. +Bugsee.testNativeCrash(); +``` + +- `testJsCrash()` throws a JavaScript `Error` where you call it. Call it from a button handler, where nothing catches it, so it reaches the global handler. In a development build, React Native also shows its error screen. +- `testNativeCrash()` raises a native test crash: a Java `RuntimeException` on Android, an `NSException` on iOS. The report is sent at the next launch. + +On iOS, run both on a physical device; see [iOS Simulator](#native-crashes). + +## Report severity + +Crash reports get `IssueSeverity.Blocker` and error reports `IssueSeverity.High` by default, on both platforms. Change the defaults with `com.bugsee.option.reporting.defaults.crash-priority` and `com.bugsee.option.reporting.defaults.error-priority` (see [Default severities](/sdk/react_native/manual/bug-reporting#default-severities)), or set a severity on individual reports from a [report handler](/sdk/react_native/report-handler). `logException` has no severity option. + +## Related pages + +- [Error boundary](/sdk/react_native/error-boundary): report render errors and show a fallback. +- [Report handler](/sdk/react_native/report-handler): add labels and attachments to crash and error reports. +- [Symbolication](/sdk/react_native/symbolication/overview): readable stack traces in release builds. +- [Configuration](/sdk/react_native/configuration#detection): the detection options. diff --git a/sidebars.ts b/sidebars.ts index 29da66a..2ecb106 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -593,6 +593,11 @@ const sidebars: SidebarsConfig = { id: "sdk/react_native/manual/bug-reporting", label: "Bug reporting", }, + { + type: "doc", + id: "sdk/react_native/manual/crash-error-reporting", + label: "Crash & error reporting", + }, ], }, { From 5cba2bb2d1839015b4e030681151ad839a16c233 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Mon, 19 Oct 2026 23:15:40 +0500 Subject: [PATCH 10/49] docs(react-native): Error boundary (7.x beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ErrorBoundary component: props, element and function fallbacks, resetError with onReset, onError, options, how a caught error is reported (handled, with the component stack, once per error, regardless of detect.crash), what it does not catch, and the 6.x differences. Verified against src/exceptions/ ErrorBoundary.tsx and its tests, and the 6.x src/lib/src/errorboundary.tsx. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: If410237ced76c252d5eeec7910c96e840eae8e4a --- docs/sdk/react_native/error-boundary.mdx | 146 +++++++++++++++++++++++ sidebars.ts | 5 + 2 files changed, 151 insertions(+) create mode 100644 docs/sdk/react_native/error-boundary.mdx diff --git a/docs/sdk/react_native/error-boundary.mdx b/docs/sdk/react_native/error-boundary.mdx new file mode 100644 index 0000000..c9d6f9f --- /dev/null +++ b/docs/sdk/react_native/error-boundary.mdx @@ -0,0 +1,146 @@ +--- +title: "Error boundary" +description: "Catch render errors in a React component tree with the ErrorBoundary component of Bugsee React Native SDK 7.x, report them to Bugsee, and render a fallback." +sidebar_position: 5 +slug: "/sdk/react_native/error-boundary" +--- + +:::warning[Beta] +This page documents Bugsee React Native SDK **7.x**, which is in beta and can change between betas. The stable release is **6.x**: see the [6.x documentation](/sdk/react_native/v6/installation). Upgrading? See [Migrating from 6.x to 7.x](/sdk/react_native/migration). +::: + +`` is a React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) that reports what it catches to Bugsee. When a component below it throws while rendering, it reports the error as a handled **error** report, with the React component stack, and renders a fallback in place of the broken tree. + +Use it around parts of your app that can fail on their own (a screen, a widget, a list item) so the rest of the app keeps working. Errors that no boundary catches are still reported, as crashes, when your root component is wrapped in `Bugsee.wrap`; see [Render errors](/sdk/react_native/manual/crash-error-reporting#render-errors). + +```tsx +import { Text } from 'react-native'; +import { ErrorBoundary } from '@bugsee/react-native'; + +export function CartScreen() { + return ( + The cart could not be shown.}> + + + ); +} +``` + +`ErrorBoundary` is a named export of `@bugsee/react-native`. It is not a property of the default `Bugsee` export, as it was in 6.x. + +## Props + +| Prop | Type | Description | +| --- | --- | --- | +| `children` | `ReactNode` | The tree to guard. | +| `fallback` | `ReactElement` or `(props: ErrorBoundaryFallbackProps) => ReactNode` | What to render after an error. Without it, the boundary renders nothing. | +| `onError` | `(error: unknown, componentStack: string \| undefined) => void` | Called after each caught error. | +| `onReset` | `(error: unknown, componentStack: string \| undefined) => void` | Called when `resetError()` runs, before the children render again. | +| `options` | `ExceptionOptions` | Options for the report, as for [`Bugsee.logException`](/sdk/react_native/manual/crash-error-reporting#options): `{ domain }`. | + +The prop types are exported as `ErrorBoundaryProps` and `ErrorBoundaryFallbackProps`. + +## Fallback + +`fallback` takes two forms. + +**An element**, rendered as is: + +```tsx +Something went wrong.}> + + +``` + +**A function**, called with an `ErrorBoundaryFallbackProps` object, so the fallback can show the error and offer a retry: + +```tsx +import { Button, Text, View } from 'react-native'; +import { ErrorBoundary, type ErrorBoundaryFallbackProps } from '@bugsee/react-native'; + +function ProfileFallback({ error, resetError }: ErrorBoundaryFallbackProps) { + return ( + + Profile failed to load: {String(error)} + )} From ab1bf997a3572fb2084c42923c36426edb33bda0 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:33:08 +0500 Subject: [PATCH 35/49] docs(react-native): address review: error boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit State the reset helper naming difference plainly: 6.x resetErrorBoundary, 7.x resetError. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Iba72d9d2218a8c24b95e518d1fad5653bc1028d8 --- docs/sdk/react_native/error-boundary.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/react_native/error-boundary.mdx b/docs/sdk/react_native/error-boundary.mdx index c9d6f9f..cdc6b99 100644 --- a/docs/sdk/react_native/error-boundary.mdx +++ b/docs/sdk/react_native/error-boundary.mdx @@ -137,7 +137,7 @@ Those reach Bugsee through the global handlers instead, as crashes or errors; se `fallback`, `onError` and `onReset` keep their roles. If you passed a function as the boundary's children in 6.x, render its result as an element instead (`` rather than `{() => }`), and rename `resetErrorBoundary` to `resetError` in your fallback. -The [6.x page](/sdk/react_native/v6/errorboundary) shows `resetError` in its example, but the 6.x code passes `resetErrorBoundary`; a 6.x fallback that worked used `resetErrorBoundary`. +The reset helper has a different name in each version: 6.x passes `resetErrorBoundary` to a `fallback` function, 7.x passes `resetError`. See the [6.x page](/sdk/react_native/v6/errorboundary) for the 6.x API. ## Related pages From 42d6d1a3dc3b378f9d71905de9420322ce9b0144 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:33:09 +0500 Subject: [PATCH 36/49] docs(react-native): address review: expo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requirements: note the iOS 15.1 floor with CocoaPods, which expo prebuild generates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: If0afdc28430817c07c7ebd23fa6b32545f99e786 --- docs/sdk/react_native/expo.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/react_native/expo.mdx b/docs/sdk/react_native/expo.mdx index 422a02d..4ef26ec 100644 --- a/docs/sdk/react_native/expo.mdx +++ b/docs/sdk/react_native/expo.mdx @@ -15,7 +15,7 @@ The config plugin covers the **build**. Your app still starts the SDK from JavaS ## Requirements -The same as for any `@bugsee/react-native` app: React Native 0.81 or later with the New Architecture, Hermes, iOS 15.0 or later and Android API 21 or later. Any Expo SDK whose React Native is 0.81 or later meets this; the package's own Expo example uses Expo SDK 57 with React Native 0.86. The plugin edits Groovy Gradle files only; see [Limits](#limits). +The same as for any `@bugsee/react-native` app: React Native 0.81 or later with the New Architecture, Hermes, iOS 15.0 or later (15.1 with CocoaPods; see [Installation](/sdk/react_native/installation#requirements)) and Android API 21 or later. Any Expo SDK whose React Native is 0.81 or later meets this; the package's own Expo example uses Expo SDK 57 with React Native 0.86. The plugin edits Groovy Gradle files only; see [Limits](#limits). :::caution[No Expo Go] The package contains native code, so it does not run in Expo Go: the native module is looked up when the package loads, and is missing there. Use a [development build](https://docs.expo.dev/develop/development-builds/introduction/) instead. From a86df8e45d984ba68087b9c4c683bc6f6911713f Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:33:22 +0500 Subject: [PATCH 37/49] docs(react-native): address review: feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the e-mail screen sentence into three plain sentences. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I929adae85af5be6ef4f47433e9f44e4702071672 --- docs/sdk/react_native/feedback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/react_native/feedback.md b/docs/sdk/react_native/feedback.md index 3159c95..b61e998 100644 --- a/docs/sdk/react_native/feedback.md +++ b/docs/sdk/react_native/feedback.md @@ -45,7 +45,7 @@ function ContactSupportButton() { Call the feedback functions after `Bugsee.launch` has resolved. On Android, `showFeedbackUI()` does nothing before launch. On iOS the chat opens before launch, but nothing is sent until the SDK has launched. If the native module is not linked (for example, the app was not rebuilt after installing the package), importing `@bugsee/react-native-feedback` throws. -Before the conversation starts, the chat shows an e-mail screen, until the user continues or skips it, where the user can leave an address for replies. When the [user identifier](/sdk/react_native/user-session-data#user-identity) contains an `@`, the chat takes it as the user's address and does not ask. Android checks the identifier once per launch, at the first feedback call, so set the identifier before your first feedback call. On iOS, the chat's messages carry the user identifier when the user gave no address. +Before the conversation starts, the chat shows an e-mail screen. On this screen the user can leave an address for replies. The screen stays until the user continues or skips it. When the [user identifier](/sdk/react_native/user-session-data#user-identity) contains an `@`, the chat takes it as the user's address and does not ask. Android checks the identifier once per launch, at the first feedback call, so set the identifier before your first feedback call. On iOS, the chat's messages carry the user identifier when the user gave no address. ## Greeting From 295f6d99446759d6c10e28fe82cce6244c69c6b8 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:33:23 +0500 Subject: [PATCH 38/49] docs(react-native): address review: logs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit requiresFiltering example now logs a token=... value that the documented filter redacts, not an e-mail address. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I79770a0e89e19a839ef521af9200c538c6953d24 --- docs/sdk/react_native/logs.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sdk/react_native/logs.mdx b/docs/sdk/react_native/logs.mdx index c3a11d0..59f3a5d 100644 --- a/docs/sdk/react_native/logs.mdx +++ b/docs/sdk/react_native/logs.mdx @@ -86,9 +86,9 @@ Bugsee.log('Payment succeeded', LogLevel.Info); Bugsee.log('Retrying request', LogLevel.Warning); Bugsee.log('Upload failed', LogLevel.Error); -// Run the log filter on this line -function onSignIn(email: string): void { - Bugsee.log(`Signed in as ${email}`, LogLevel.Info, true); +// Run the log filter on this line (the filter below redacts token=...) +function onSessionRefreshed(sessionToken: string): void { + Bugsee.log(`Session refreshed: token=${sessionToken}`, LogLevel.Info, true); } ``` From 6ebdbe03947be63e985c9f46d5afe2c3617cc650 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:33:34 +0500 Subject: [PATCH 39/49] docs(react-native): address review: crash & error reporting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three bullets follow, so say three consequences. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ifdf75c8c13882a680145f6e99c631cc29ab1a663 --- docs/sdk/react_native/manual/crash-error-reporting.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/react_native/manual/crash-error-reporting.mdx b/docs/sdk/react_native/manual/crash-error-reporting.mdx index 5fe01b7..94e3b81 100644 --- a/docs/sdk/react_native/manual/crash-error-reporting.mdx +++ b/docs/sdk/react_native/manual/crash-error-reporting.mdx @@ -145,7 +145,7 @@ For a handled, non-terminal error, use [`logException`](#reporting-handled-error Bugsee remembers every error **object** it has reported, and does not report the same object again, whichever route sees it second: `logException`, `logUnhandledException`, the global handler, the rejection tracker, `` or `Bugsee.wrap`. An error that more than one route sees produces one report from the JavaScript layer. -Two consequences: +Three consequences: - If you log an error and then rethrow it, the rethrown error is not reported again, not even as a crash. If the error is going to end the app, report it with `logUnhandledException` instead of `logException`, not after it: whichever call sees the error object first claims it, and later calls for the same object do nothing. - An error object is claimed even when its report is dropped. `logException` before `launch` claims the object although the native SDK drops the report, so no later route reports that same object. From a5dd09af7a25e2326a89ee4a7bfe989f00e27793 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:33:35 +0500 Subject: [PATCH 40/49] docs(react-native): address review: performance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reword the sampled row: the value has no effect in this beta because the standalone upload is not active. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I4ada74fd6c133b5b492afa05978739921d44f1e8 --- docs/sdk/react_native/performance.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/react_native/performance.mdx b/docs/sdk/react_native/performance.mdx index aefffc7..156b565 100644 --- a/docs/sdk/react_native/performance.mdx +++ b/docs/sdk/react_native/performance.mdx @@ -116,7 +116,7 @@ Call `finish` on these objects too: it releases the resources they hold. | `finished` | `boolean` | Whether the span has finished. | | `attributes` | object | The attributes. | | `name` | `string` | Transaction only: the transaction name. | -| `sampled` | `boolean` | Transaction only: whether the transaction won the sample-rate draw when it started (see [Sampling](#sampling)), which this beta uses for no upload. Read once at start and never updated: a transaction that adaptive sampling promotes when it finishes still reads `false`. | +| `sampled` | `boolean` | Transaction only: whether the transaction won the sample-rate draw when it started (see [Sampling](#sampling)). In this beta the value has no effect, because the standalone upload is not active. It is read once at start and never updated: a transaction that adaptive sampling promotes when it finishes still reads `false`. | The properties are read when the object is created and then follow the changes you make through it. They are not read again. From bb30178d5ce4c1855ff5e049da9c8cc187952700 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:34:24 +0500 Subject: [PATCH 41/49] docs(react-native): address review: privacy network MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sample filter now covers the iOS built-in header names and URL/JSON keys (BGSNetworkDataSanitizer.m), matched case-insensitively, since on iOS a filter replaces the built-in redaction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I62ac8e97525210ce38dafcfe7bd09817afbc2eaf --- cspell.json | 2 ++ docs/sdk/react_native/privacy/network.md | 33 +++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/cspell.json b/cspell.json index 12addde..2cd046e 100644 --- a/cspell.json +++ b/cspell.json @@ -82,6 +82,8 @@ "androidx", "Bugsee", "bugsee", + "creditcard", + "cardnumber", "symbolicate", "symbolication", "symbolicated", diff --git a/docs/sdk/react_native/privacy/network.md b/docs/sdk/react_native/privacy/network.md index b3061d3..bae79c1 100644 --- a/docs/sdk/react_native/privacy/network.md +++ b/docs/sdk/react_native/privacy/network.md @@ -65,22 +65,35 @@ Write one filter that redacts everything you need on both platforms, as in the e `Bugsee.setNetworkFilter(callback)` sees each network event before it is recorded, the captured traffic and the events you add with `addNetworkEvent`. Return the event with its fields redacted to keep it, or `null` to drop it. +The example below is a starting point, not an exhaustive policy: review it against your data. Its lists repeat the iOS built-in header names and keys, because on iOS the filter replaces the built-in redaction, and add a few names for your own API. All names are matched case-insensitively. + ```ts import Bugsee, { type NetworkFilterEvent } from '@bugsee/react-native'; +// Header names (lowercase). The first nine are the iOS built-in list. const SECRET_HEADERS = new Set([ - 'authorization', - 'proxy-authorization', - 'cookie', - 'set-cookie', - 'x-api-key', - 'x-session-id', + 'authorization', 'proxy-authorization', 'cookie', 'set-cookie', 'x-api-key', + 'x-auth-token', 'x-csrf-token', 'x-forwarded-for', 'x-real-ip', + 'x-session-id', // your own API +]); + +// URL query parameter and JSON key names (lowercase). All but the last line are the iOS built-in list. +const SECRET_KEYS = new Set([ + 'password', 'passwd', 'pass', 'secret', 'client_secret', + 'token', 'access_token', 'refresh_token', 'id_token', 'auth_token', + 'api_key', 'apikey', 'authorization', + 'credit_card', 'creditcard', 'card_number', 'cardnumber', 'cvv', 'cvc', 'cvv2', + 'ssn', 'social_security', 'pin', 'private_key', 'privatekey', + 'otp', 'code', 'session', // your own API ]); -const SECRET_PARAMS = /([?&](?:token|access_token|code|session)=)[^&#]*/gi; -const SECRET_JSON_KEYS = new Set(['password', 'otp', 'token', 'refresh_token', 'cardNumber']); function redactUrl(url: string | null): string | null { - return url === null ? null : url.replace(SECRET_PARAMS, '$1'); + if (url === null) { + return null; + } + return url.replace(/([?&])([^=&#]+)=[^&#]*/g, (match: string, sep: string, name: string) => + SECRET_KEYS.has(name.toLowerCase()) ? `${sep}${name}=` : match, + ); } function redactHeaders(headers: Record): Record { @@ -95,7 +108,7 @@ function redactBody(body: string): string | null { try { const parsed: unknown = JSON.parse(body); return JSON.stringify(parsed, (key, value: unknown) => - SECRET_JSON_KEYS.has(key) ? '' : value, + SECRET_KEYS.has(key.toLowerCase()) ? '' : value, ); } catch { return null; // not JSON: drop the body rather than guess From 8b00fe4a3ef6049df15f8488dab026137640d191 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:34:32 +0500 Subject: [PATCH 42/49] docs(react-native): address review: privacy overview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-launch: only BugseeSecure and setSecureRectangles regions wait for JavaScript; password-field and FLAG_SECURE masking do not (privacy/video.md). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I45e91fe13044f6dfcda2ab38dfe8896bcc15b6ff --- docs/sdk/react_native/privacy/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/react_native/privacy/overview.md b/docs/sdk/react_native/privacy/overview.md index 7617211..064918d 100644 --- a/docs/sdk/react_native/privacy/overview.md +++ b/docs/sdk/react_native/privacy/overview.md @@ -30,7 +30,7 @@ The controls work in four places: ## Things to know - **Install filters before `Bugsee.launch`.** A filter applies to what is recorded after it is installed, so set the log, network and breadcrumb filters, and the report handler, at the top of your startup code. -- **Android auto-launch.** With `autoLaunch` (see [Expo](/sdk/react_native/expo#auto-launch-on-android)), the SDK records from process start on Android, before any JavaScript runs. Logs, network events and breadcrumbs captured before your code calls the filter setters are recorded unfiltered, and nothing is masked until your `` components mount. Do not use auto-launch if that window must be filtered. +- **Android auto-launch.** With `autoLaunch` (see [Expo](/sdk/react_native/expo#auto-launch-on-android)), the SDK records from process start on Android, before any JavaScript runs. Logs, network events and breadcrumbs captured before your code calls the filter setters are recorded unfiltered, and the regions you mark with `` or `setSecureRectangles` are not masked until they mount or are set. Automatic masking of password fields and `FLAG_SECURE` windows does not depend on them; see [Privacy: Video](/sdk/react_native/privacy/video#password-fields). Do not use auto-launch if that window must be filtered. - **Filters and development reloads.** A filter is a function in the JavaScript runtime. After a JavaScript reload the filters stay on while nothing in the new runtime answers them, so network events and breadcrumbs are lost until your code installs the filter again. On Android the log filter is turned off on reload, so log lines are recorded **unfiltered** until `setLogFilter` runs again. Install the filters first thing in your startup code. - **Performance spans.** With performance monitoring on (the default), the SDK records a performance transaction for each HTTP request, carrying its URL, and on iOS spans for file operations, carrying file paths. They are included in every report. Your network filter does not reach them. Span URLs get the built-in network redaction on Android, and are recorded in full, query string included, on iOS; see [Privacy: Network](/sdk/react_native/privacy/network). `com.bugsee.option.performance.enabled` set to `false` turns them off. See [Performance monitoring](/sdk/react_native/performance). - **The platforms differ.** On Android the built-in network redaction runs before your network filter; on iOS your filter replaces it. See [Privacy: Network](/sdk/react_native/privacy/network). From e997cb12763ab36b447fc009cf3e51c197a7e42a Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:34:41 +0500 Subject: [PATCH 43/49] docs(react-native): address review: user & session data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sign-out example clears the attributes too (clearAllAttributes returns Promise, src/index.ts). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I026fa05077a54c9f833ce69f027a4d7ddd31e732 --- docs/sdk/react_native/user-session-data.mdx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/sdk/react_native/user-session-data.mdx b/docs/sdk/react_native/user-session-data.mdx index 3dd9020..b6f1072 100644 --- a/docs/sdk/react_native/user-session-data.mdx +++ b/docs/sdk/react_native/user-session-data.mdx @@ -27,8 +27,11 @@ async function logCurrentUser() { console.log('Bugsee user:', id ?? 'none'); } -// On sign-out -Bugsee.clearUserIdentifier(); +// On sign-out: attributes persist across launches, so clear them too +async function onSignOut(): Promise { + Bugsee.clearUserIdentifier(); + await Bugsee.clearAllAttributes(); +} ``` | Method | Returns | Notes | From 4b82d639dbd11b7da7fb2a81e72b5c6940797d8c Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:35:14 +0500 Subject: [PATCH 44/49] docs(react-native): address review: redirects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Old React Native routes with no 7.x page (custom, crashes, errorboundary, manual) redirect to their 6.x pages; add the v6 and v6/privacy section roots. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ide5f162eb920facab5c63d11d1a4f55922b3e7e4 --- docusaurus.config.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 508ccd4..0f4bc40 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -102,6 +102,13 @@ const config: Config = { { from: '/sdk/android/v7/detection', to: '/sdk/android/issue-detection/' }, { from: '/sdk/android/v7/extensions', to: '/sdk/android/extensibility/bugsee-extensions/' }, { from: '/sdk/android/v7/manual', to: '/sdk/android/manual/bug-reporting/' }, + // React Native 6.x pages moved under /sdk/react_native/v6/; old routes with no 7.x page keep their 6.x content. + { from: '/sdk/react_native/custom', to: '/sdk/react_native/v6/custom/' }, + { from: '/sdk/react_native/crashes', to: '/sdk/react_native/v6/crashes/' }, + { from: '/sdk/react_native/errorboundary', to: '/sdk/react_native/v6/errorboundary/' }, + { from: '/sdk/react_native/manual', to: '/sdk/react_native/v6/manual/' }, + { from: '/sdk/react_native/v6', to: '/sdk/react_native/v6/installation/' }, + { from: '/sdk/react_native/v6/privacy', to: '/sdk/react_native/v6/privacy/overview/' }, ], // Android 7.x lived under /sdk/android/v7/ until it became the default; // every current Android page keeps answering at its old v7 address. From 4f72c93f77aa1afc81749f1c2c0e8331ec9d8b9e Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:35:21 +0500 Subject: [PATCH 45/49] docs(ios): release notes link the 6.x React Native logs page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'React native custom logger' entry is a 6.x feature; link /sdk/react_native/v6/logs/ instead of the 7.x page. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Icf1c7448cb2f7cfbff59ef61b643e3988bf0e06a --- docs/sdk/ios/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/ios/release-notes.md b/docs/sdk/ios/release-notes.md index b0ab2df..a93d5be 100644 --- a/docs/sdk/ios/release-notes.md +++ b/docs/sdk/ios/release-notes.md @@ -627,7 +627,7 @@ It is controlled by sanitizeNetworkData/BugseeSanitizeNetworkDataKey option (def - Feature: Refactor logging capturing system to produce cleaner logs - Feature: Better handling of multi-window hierarchies, lower cpu load. - Feature: Auto-hide CC text fields in common payment libraries (Stripe, Braintree, card.io) -- Feature: Add React native custom logger [read more](/sdk/react_native/logs/) +- Feature: Add React native custom logger [read more](/sdk/react_native/v6/logs/) - Bug fix: Incorrect addresses in C++ exceptions in some cases From c7153767e2389f91ed9a5ef5a7822f476c17c88c Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:38:18 +0500 Subject: [PATCH 46/49] docs(react-native): redirect the hyphenated spelling of the retired routes too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I0bcb31d582d5ad917c22b9c51def79d9fccdb539 --- docusaurus.config.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 0f4bc40..af1cd18 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -107,6 +107,11 @@ const config: Config = { { from: '/sdk/react_native/crashes', to: '/sdk/react_native/v6/crashes/' }, { from: '/sdk/react_native/errorboundary', to: '/sdk/react_native/v6/errorboundary/' }, { from: '/sdk/react_native/manual', to: '/sdk/react_native/v6/manual/' }, + // The hyphenated spelling is generated only for pages that exist, so the retired routes need it explicitly. + { from: '/sdk/react-native/custom', to: '/sdk/react_native/v6/custom/' }, + { from: '/sdk/react-native/crashes', to: '/sdk/react_native/v6/crashes/' }, + { from: '/sdk/react-native/errorboundary', to: '/sdk/react_native/v6/errorboundary/' }, + { from: '/sdk/react-native/manual', to: '/sdk/react_native/v6/manual/' }, { from: '/sdk/react_native/v6', to: '/sdk/react_native/v6/installation/' }, { from: '/sdk/react_native/v6/privacy', to: '/sdk/react_native/v6/privacy/overview/' }, ], From 16df4ba13916cebeee29a2e0ace5f199c2d59ce1 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 07:50:30 +0500 Subject: [PATCH 47/49] docs(react-native): redirect the hyphenated spelling of the v6 section roots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I4a9b5a2583a49b8a1dfec5eb4cba8929d841437b --- docusaurus.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index af1cd18..047b1d9 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -112,6 +112,8 @@ const config: Config = { { from: '/sdk/react-native/crashes', to: '/sdk/react_native/v6/crashes/' }, { from: '/sdk/react-native/errorboundary', to: '/sdk/react_native/v6/errorboundary/' }, { from: '/sdk/react-native/manual', to: '/sdk/react_native/v6/manual/' }, + { from: '/sdk/react-native/v6', to: '/sdk/react_native/v6/installation/' }, + { from: '/sdk/react-native/v6/privacy', to: '/sdk/react_native/v6/privacy/overview/' }, { from: '/sdk/react_native/v6', to: '/sdk/react_native/v6/installation/' }, { from: '/sdk/react_native/v6/privacy', to: '/sdk/react_native/v6/privacy/overview/' }, ], From 0cef696d4d3dccc2187c67fff82207cccd619a99 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 08:14:36 +0500 Subject: [PATCH 48/49] docs(react-native): FAQ and Installation: what happens if Hermes is turned off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I1ae31b2dc40e6e61184fc0435a98562eed0ca82f --- docs/sdk/react_native/faq.md | 6 ++++-- docs/sdk/react_native/installation.mdx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/sdk/react_native/faq.md b/docs/sdk/react_native/faq.md index 2556bdc..9646256 100644 --- a/docs/sdk/react_native/faq.md +++ b/docs/sdk/react_native/faq.md @@ -17,9 +17,11 @@ React Native 0.81 or later, with the New Architecture enabled, on iOS 15.0 or la
-**2. Can I use JavaScriptCore instead of Hermes?** +**2. Can I use JavaScriptCore instead of Hermes? What happens if I turn Hermes off?** -No. Hermes is required. React Native removed JavaScriptCore from core in 0.81, and the community package that replaces it, `@react-native-community/javascriptcore`, does not work with current React Native. See [Overview](/sdk/react_native/overview#requirements). +Hermes is required, and JavaScriptCore is not supported. React Native removed JavaScriptCore from core in 0.81, so turning Hermes off means plugging in a third-party engine. The only one the ecosystem offers, `@react-native-community/javascriptcore`, did not work with current React Native when we tried it. On Android its JavaScriptCore cannot parse React Native's own bundle, and on iOS it fails to link on 0.87 and to `pod install` on 0.86. An app that turns Hermes off therefore usually cannot be built, before the Bugsee SDK is involved. + +Nothing in the SDK blocks or warns about it, and some code adapts to it. Reports carry `js-engine: jsc` (for any engine that is not Hermes), stack traces are parsed in both engines' formats, unhandled promise rejections use the standard promise library's tracker, and the source-map build hooks have a plain-bundle path. None of this has been tested, because no test app could be built, so treat it as unsupported. If you try it anyway, report what you find together with your engine and React Native versions. See [Overview](/sdk/react_native/overview#requirements).
diff --git a/docs/sdk/react_native/installation.mdx b/docs/sdk/react_native/installation.mdx index e0688ab..3086d03 100644 --- a/docs/sdk/react_native/installation.mdx +++ b/docs/sdk/react_native/installation.mdx @@ -27,7 +27,7 @@ This page covers a React Native CLI (bare) app, where you own the `ios/` and `an | iOS | 15.0 or later (see the note below) | | Android | API 21 or later | -The New Architecture is the default from React Native 0.76. On 0.81 it can still be turned off; this package requires it on. Hermes is required: JavaScriptCore is not supported. +The New Architecture is the default from React Native 0.76. On 0.81 it can still be turned off; this package requires it on. Hermes is required: JavaScriptCore is not supported (see the [FAQ](/sdk/react_native/faq) for what happens if you turn Hermes off). The Bugsee iOS SDK itself supports iOS 15.0. With CocoaPods, the podspec takes React Native's own minimum, which is 15.1, so that is the effective floor there. From 795a2bc08d0f6d8a6bc709903d03a0929d13e755 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Tue, 20 Oct 2026 09:32:53 +0500 Subject: [PATCH 49/49] docs(react-native): 7.0.0-beta3 release notes; scripts' executable bit fixed in beta3; current version is beta3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Iae8cdbb8ace0260eb659653c97d32e754dab1f10 --- docs/sdk/react_native/expo.mdx | 4 ++-- docs/sdk/react_native/faq.md | 2 +- docs/sdk/react_native/feedback.md | 2 +- docs/sdk/react_native/migration.mdx | 4 ++-- docs/sdk/react_native/overview.mdx | 2 +- docs/sdk/react_native/release-notes.md | 19 +++++++++++++++++-- .../react_native/symbolication/android.mdx | 6 +++--- docs/sdk/react_native/symbolication/ios.mdx | 4 ++-- .../react_native/symbolication/overview.mdx | 4 ++-- 9 files changed, 31 insertions(+), 16 deletions(-) diff --git a/docs/sdk/react_native/expo.mdx b/docs/sdk/react_native/expo.mdx index 4ef26ec..9766427 100644 --- a/docs/sdk/react_native/expo.mdx +++ b/docs/sdk/react_native/expo.mdx @@ -56,7 +56,7 @@ Run it again whenever you change the plugin's options. The plugin's edits are it Release builds then upload their source maps, and Archives upload their dSYMs, whenever a real token is set. :::caution[7.0.0-beta1 and 7.0.0-beta2: Android Release builds need `chmod`] -In 7.0.0-beta1 and 7.0.0-beta2 the package's shell scripts are published without the executable bit. The `hermesCommand` the plugin writes runs `hermesc-preserve-js.sh` directly, so an Android Release build on macOS or Linux fails with "Permission denied". Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` after each install, for example from a `postinstall` script; see [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps). The iOS bundle phase the plugin writes runs its script through `/bin/bash` and is not affected. +In 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) the package's shell scripts are published without the executable bit. The `hermesCommand` the plugin writes runs `hermesc-preserve-js.sh` directly, so an Android Release build on macOS or Linux fails with "Permission denied". Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` after each install, for example from a `postinstall` script; see [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps). The iOS bundle phase the plugin writes runs its script through `/bin/bash` and is not affected. ::: ## 4. Launch the SDK @@ -86,7 +86,7 @@ See [Installation](/sdk/react_native/installation#4-launch-bugsee) for what `lau | `symbolicateReactNativeFrameworks` | boolean | `false` | Make `pod install` download React Native's own dSYMs, so React frames in iOS crashes symbolicate. See [React Native's dSYMs](#react-native-dsyms-on-ios). | | `autoLaunch` | boolean | `false` | Android only. Writes the `com.bugsee.app-token` manifest meta-data, so the native SDK launches at process start. See [Auto-launch on Android](#auto-launch-on-android). | | `endpoint` | string | none (production) | A self-hosted, staging or regional Bugsee API base. See [Custom endpoint](#custom-endpoint). | -| `gradlePluginVersion` | string | the version the package is built against (4.0.8 in `7.0.0-beta2`) | The `com.bugsee.android.gradle` version to declare. | +| `gradlePluginVersion` | string | the version the package is built against (4.0.8 in `7.0.0-beta3`) | The `com.bugsee.android.gradle` version to declare. | ## What the plugin changes diff --git a/docs/sdk/react_native/faq.md b/docs/sdk/react_native/faq.md index 9646256..3fd606d 100644 --- a/docs/sdk/react_native/faq.md +++ b/docs/sdk/react_native/faq.md @@ -117,7 +117,7 @@ This is not caused by Bugsee: it affects React Native 0.81 and 0.82 with Xcode 2 **18. A Release build fails with "Permission denied" on `hermesc-preserve-js.sh` or `bugsee-xcode.sh`.** -In 7.0.0-beta1 and 7.0.0-beta2 the package's shell scripts are published without the executable bit. On Android (bare and Expo, on macOS or Linux) and in a bare app's iOS bundle phase, they are run directly and fail. Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` after every install, for example from a `postinstall` script, or on iOS run the script through `/bin/bash`. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). +In 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) the package's shell scripts are published without the executable bit. On Android (bare and Expo, on macOS or Linux) and in a bare app's iOS bundle phase, they are run directly and fail. Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` after every install, for example from a `postinstall` script, or on iOS run the script through `/bin/bash`. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps).
diff --git a/docs/sdk/react_native/feedback.md b/docs/sdk/react_native/feedback.md index b61e998..e444af7 100644 --- a/docs/sdk/react_native/feedback.md +++ b/docs/sdk/react_native/feedback.md @@ -13,7 +13,7 @@ Bugsee includes an in-app chat that lets your users talk to your support team an ## Installation -Add the feedback package next to `@bugsee/react-native`. The two must be the **same release**: install both at the same version, or both with the `@beta` tag. Nothing enforces it: the package's peer dependency accepts any `@bugsee/react-native` from `7.0.0-beta2` on. +Add the feedback package next to `@bugsee/react-native`. The two must be the **same release**: install both at the same version, or both with the `@beta` tag. Nothing enforces it: the package's peer dependency accepts any `@bugsee/react-native` from `7.0.0-beta3` on. ```sh yarn add @bugsee/react-native@beta @bugsee/react-native-feedback@beta diff --git a/docs/sdk/react_native/migration.mdx b/docs/sdk/react_native/migration.mdx index 57e714c..dea3766 100644 --- a/docs/sdk/react_native/migration.mdx +++ b/docs/sdk/react_native/migration.mdx @@ -13,7 +13,7 @@ This page documents Bugsee React Native SDK **7.x**, which is in beta and can ch ::: :::note -This guide compares `react-native-bugsee` 6.0.x with `@bugsee/react-native` `7.0.0-beta2`. If you are setting up a new project, start from [Installation](/sdk/react_native/installation) instead. +This guide compares `react-native-bugsee` 6.0.x with `@bugsee/react-native` `7.0.0-beta3`. If you are setting up a new project, start from [Installation](/sdk/react_native/installation) instead. ::: This guide walks through every public-API change between the 6.x package (`react-native-bugsee`) and the 7.x package (`@bugsee/react-native`, plus `@bugsee/react-native-feedback` for the feedback chat). @@ -641,7 +641,7 @@ These are documented on the pages linked: - One created report at a time, with no call to discard it. See [One created report at a time](/sdk/react_native/manual/bug-reporting#one-created-report-at-a-time). - `deleteCollectedDataOnDevice` keeps finished reports waiting for upload. See [Cleanup](/sdk/react_native/privacy/cleanup). - On iOS, most feedback chat colors have no effect. See [Feedback](/sdk/react_native/feedback#appearance). -- In 7.0.0-beta1 and 7.0.0-beta2 the package's shell scripts are published without the executable bit, so the Android Release bundle task (bare and Expo) and the bare iOS bundle phase fail with "Permission denied" until you `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` or run the iOS script through `/bin/bash`. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). +- In 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) the package's shell scripts are published without the executable bit, so the Android Release bundle task (bare and Expo) and the bare iOS bundle phase fail with "Permission denied" until you `chmod +x node_modules/@bugsee/react-native/scripts/*.sh` or run the iOS script through `/bin/bash`. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). --- diff --git a/docs/sdk/react_native/overview.mdx b/docs/sdk/react_native/overview.mdx index 8c62830..3f25c7a 100644 --- a/docs/sdk/react_native/overview.mdx +++ b/docs/sdk/react_native/overview.mdx @@ -59,7 +59,7 @@ Hermes is required. JavaScriptCore (Hermes off) is not supported: React Native r ## Versions -This beta, `7.0.0-beta2`, is built on these native SDKs: +This beta, `7.0.0-beta3`, is built on these native SDKs: | Platform | Native SDK | Notes | | --- | --- | --- | diff --git a/docs/sdk/react_native/release-notes.md b/docs/sdk/react_native/release-notes.md index 4c84eed..35bcb9d 100644 --- a/docs/sdk/react_native/release-notes.md +++ b/docs/sdk/react_native/release-notes.md @@ -13,6 +13,21 @@ Release history for Bugsee React Native SDK 7.x: `@bugsee/react-native` and `@bu Each release lists the native SDKs it is built on. Their own changes are in the native SDK release notes: [Android](/sdk/android/release-notes) and [iOS 7.x](/sdk/ios/v7/release-notes). +## 7.0.0-beta3 (October 20 2026) + +Fixes the package's shell scripts, which 7.0.0-beta1 and 7.0.0-beta2 published without the executable bit. + +**Fixes** + +- **Release builds work without a `chmod`.** `scripts/bugsee-xcode.sh` and `scripts/hermesc-preserve-js.sh` (and the two Node scripts next to them) are now published as executable. Android Release builds on macOS and Linux, and the bundle phase of a bare iOS app, no longer fail with "Permission denied". If you added the `chmod +x` workaround for 7.0.0-beta1 or 7.0.0-beta2, you can remove it after upgrading. The release process now packs with `npm pack` and fails if a file that is executable in the repository is not executable in the package. +- `@bugsee/react-native-feedback` requires `@bugsee/react-native` `^7.0.0-beta3`. + +**Compatibility** + +- Android: Bugsee Android SDK 7.4.2, Bugsee Gradle plugin 4.0.8. +- iOS: Bugsee iOS SDK 7.0.0-beta7. +- `@bugsee/cli` 0.7.12. + ## 7.0.0-beta2 (October 19 2026) `launch` and `relaunch` take the options object as is. @@ -36,7 +51,7 @@ Each release lists the native SDKs it is built on. Their own changes are in the **Known issues** -- The package's shell scripts (`scripts/bugsee-xcode.sh`, `scripts/hermesc-preserve-js.sh`) are published without the executable bit. Android Release builds on macOS and Linux, and the bundle phase of a bare iOS app, fail with "Permission denied" until you run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh`. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). +- The package's shell scripts (`scripts/bugsee-xcode.sh`, `scripts/hermesc-preserve-js.sh`) are published without the executable bit. Android Release builds on macOS and Linux, and the bundle phase of a bare iOS app, fail with "Permission denied" until you run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh`. Fixed in 7.0.0-beta3. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). **Compatibility** @@ -67,7 +82,7 @@ The first public beta of the rewritten React Native SDK. `@bugsee/react-native` **Known issues** -- The package's shell scripts (`scripts/bugsee-xcode.sh`, `scripts/hermesc-preserve-js.sh`) are published without the executable bit. Android Release builds on macOS and Linux, and the bundle phase of a bare iOS app, fail with "Permission denied" until you run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh`. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). +- The package's shell scripts (`scripts/bugsee-xcode.sh`, `scripts/hermesc-preserve-js.sh`) are published without the executable bit. Android Release builds on macOS and Linux, and the bundle phase of a bare iOS app, fail with "Permission denied" until you run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh`. Fixed in 7.0.0-beta3. See [Symbolication: Android](/sdk/react_native/symbolication/android#1-javascript-source-maps) and [Symbolication: iOS](/sdk/react_native/symbolication/ios#1-the-bundle-phase-javascript-source-maps). **Compatibility** diff --git a/docs/sdk/react_native/symbolication/android.mdx b/docs/sdk/react_native/symbolication/android.mdx index d6337a6..8c0db4d 100644 --- a/docs/sdk/react_native/symbolication/android.mdx +++ b/docs/sdk/react_native/symbolication/android.mdx @@ -49,7 +49,7 @@ What the two edits do: If Hermes compiles a bundle without going through the wrapper, the bundle task fails instead of shipping a Release without a debug ID. See [Troubleshooting](#troubleshooting). :::caution[7.0.0-beta1 and 7.0.0-beta2: scripts without the executable bit] -In 7.0.0-beta1 and 7.0.0-beta2 the package's shell scripts are published without the executable bit (mode 644). React Native runs `hermesCommand` directly, so on macOS and Linux the Release bundle task fails with "Permission denied" on `hermesc-preserve-js.sh`. Windows, which uses the `.cmd` launcher, is not affected. Expo apps are affected too, since the config plugin writes the same `hermesCommand`. Make the scripts executable after every install, for example from a `postinstall` script in your app's `package.json`: +In 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) the package's shell scripts are published without the executable bit (mode 644). React Native runs `hermesCommand` directly, so on macOS and Linux the Release bundle task fails with "Permission denied" on `hermesc-preserve-js.sh`. Windows, which uses the `.cmd` launcher, is not affected. Expo apps are affected too, since the config plugin writes the same `hermesCommand`. Make the scripts executable after every install, for example from a `postinstall` script in your app's `package.json`: ```json title="package.json" { @@ -82,7 +82,7 @@ The Bugsee Gradle plugin (`com.bugsee.android.gradle`) uploads the R8/ProGuard m It is also what records `fetch` and `XMLHttpRequest` on Android: React Native sends them through OkHttp, and the plugin is what lets the SDK record OkHttp traffic. Without the plugin, those requests are not recorded on Android; see [Network events](/sdk/react_native/network). -Use the plugin version the package is built against: `android.gradlePlugin` in `node_modules/@bugsee/react-native/native-versions.json`, which is **4.0.8** for `7.0.0-beta2`. Its requirements (Android Gradle Plugin and Gradle versions) are on [Gradle plugin requirements](/sdk/android/gradle-plugin/requirements). +Use the plugin version the package is built against: `android.gradlePlugin` in `node_modules/@bugsee/react-native/native-versions.json`, which is **4.0.8** for `7.0.0-beta3`. Its requirements (Android Gradle Plugin and Gradle versions) are on [Gradle plugin requirements](/sdk/android/gradle-plugin/requirements). **`android/settings.gradle`**: the plugin is published to Maven Central, which Gradle does not search for plugins unless told to: @@ -187,7 +187,7 @@ A `hermesCommand` that an earlier prebuild wrote (the `.sh` launcher on every op **The bundle task fails with "compiled the bundle with Hermes, but hermesc did not run through the preserve wrapper".** `bugsee-sourcemaps.gradle` is applied, but `react.hermesCommand` does not point at the package's launcher, so the bundle would ship without a debug ID. Set `hermesCommand` as in [JavaScript source maps](#1-javascript-source-maps). -**On macOS or Linux, the bundle task fails with "Permission denied" on `hermesc-preserve-js.sh`.** The scripts of 7.0.0-beta1 and 7.0.0-beta2 are published without the executable bit. Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh`, ideally from a `postinstall` script; see the caution in [JavaScript source maps](#1-javascript-source-maps). +**On macOS or Linux, the bundle task fails with "Permission denied" on `hermesc-preserve-js.sh`.** The scripts of 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) are published without the executable bit. Run `chmod +x node_modules/@bugsee/react-native/scripts/*.sh`, ideally from a `postinstall` script; see the caution in [JavaScript source maps](#1-javascript-source-maps). **On Windows, the bundle task fails with "would run hermesc through … a shell script".** Your `hermesCommand` names `hermesc-preserve-js.sh`, which earlier instructions gave for every OS. `cmd` cannot run it. Use the per-OS line above, which picks `hermesc-preserve-js.cmd` on Windows. diff --git a/docs/sdk/react_native/symbolication/ios.mdx b/docs/sdk/react_native/symbolication/ios.mdx index 59162e7..c1ff711 100644 --- a/docs/sdk/react_native/symbolication/ios.mdx +++ b/docs/sdk/react_native/symbolication/ios.mdx @@ -34,7 +34,7 @@ REACT_NATIVE_XCODE="${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugs ``` :::caution[7.0.0-beta1 and 7.0.0-beta2: scripts without the executable bit] -In 7.0.0-beta1 and 7.0.0-beta2 the package's shell scripts are published without the executable bit (mode 644). `with-environment.sh` runs the script it is given directly, so the phase above fails with "Permission denied". Use one of these: +In 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) the package's shell scripts are published without the executable bit (mode 644). `with-environment.sh` runs the script it is given directly, so the phase above fails with "Permission denied". Use one of these: - **Run the script through `/bin/bash`**, as the Expo config plugin's phase does. This phase reads `.xcode.env` and `.xcode.env.local` the same way, then runs `bugsee-xcode.sh` with `bash`, so it works with or without the executable bit: @@ -249,7 +249,7 @@ With the [config plugin](/sdk/react_native/expo), `expo prebuild` makes all of t ## Troubleshooting -**The bundle phase fails with "Permission denied" on `bugsee-xcode.sh`.** The scripts of 7.0.0-beta1 and 7.0.0-beta2 are published without the executable bit. Run the script through `/bin/bash`, or `chmod +x` the package's scripts after each install; see the caution in [The bundle phase](#1-the-bundle-phase-javascript-source-maps). +**The bundle phase fails with "Permission denied" on `bugsee-xcode.sh`.** The scripts of 7.0.0-beta1 and 7.0.0-beta2 (fixed in 7.0.0-beta3) are published without the executable bit. Run the script through `/bin/bash`, or `chmod +x` the package's scripts after each install; see the caution in [The bundle phase](#1-the-bundle-phase-javascript-source-maps). **`bugsee: source map upload skipped: no app token is configured`** (or `the app token is the placeholder`). The bundle phase has no real token. Export `BUGSEE_APP_TOKEN` in `ios/.xcode.env.local`; a plain assignment without `export` does not reach the script. diff --git a/docs/sdk/react_native/symbolication/overview.mdx b/docs/sdk/react_native/symbolication/overview.mdx index ced6e4f..acedc35 100644 --- a/docs/sdk/react_native/symbolication/overview.mdx +++ b/docs/sdk/react_native/symbolication/overview.mdx @@ -48,9 +48,9 @@ Before upload, the hooks rewrite absolute paths in the map's `sources` to paths | Piece | What it is | What it does here | | --- | --- | --- | -| `@bugsee/cli` | The Bugsee CLI, a dependency of `@bugsee/react-native` (pinned exactly, 0.7.12 in `7.0.0-beta2`). Its binary comes from a platform-specific optional dependency. | Stamps and uploads source maps for the package's build hooks, and uploads dSYMs from the iOS post-action. See [Bugsee CLI](/cli). | +| `@bugsee/cli` | The Bugsee CLI, a dependency of `@bugsee/react-native` (pinned exactly, 0.7.12 in `7.0.0-beta3`). Its binary comes from a platform-specific optional dependency. | Stamps and uploads source maps for the package's build hooks, and uploads dSYMs from the iOS post-action. See [Bugsee CLI](/cli). | | Package build hooks | `scripts/bugsee-sourcemaps.gradle` and `scripts/hermesc-preserve-js.*` (Android), `scripts/bugsee-xcode.sh` (iOS), shipped in the package. | Give each Release bundle a debug ID and upload its source map. They do not need the Bugsee Gradle plugin. | -| Bugsee Gradle plugin | `com.bugsee.android.gradle`, version 4.0.8 for `7.0.0-beta2`. A Gradle plugin, so autolinking cannot add it. | Uploads the R8 mapping, the native symbols and the build info of each Release build, with its own copy of the CLI. It also instruments OkHttp, which is how `fetch` and `XMLHttpRequest` reach Bugsee's network capture on Android; see [Installation](/sdk/react_native/installation#android). | +| Bugsee Gradle plugin | `com.bugsee.android.gradle`, version 4.0.8 for `7.0.0-beta3`. A Gradle plugin, so autolinking cannot add it. | Uploads the R8 mapping, the native symbols and the build info of each Release build, with its own copy of the CLI. It also instruments OkHttp, which is how `fetch` and `XMLHttpRequest` reach Bugsee's network capture on Android; see [Installation](/sdk/react_native/installation#android). | | iOS bundle phase | Xcode's **Bundle React Native code and images** phase, pointed at `bugsee-xcode.sh` instead of React Native's `react-native-xcode.sh`. | Runs React Native's script, then stamps and uploads the source map. | | iOS Archive post-action | A Run Script in the scheme's **Archive** post-actions that runs `bugsee-cli xcode post-action`. | Registers the build and uploads its dSYMs, React Native's included when they are in the Archive. See [iOS build publishing](/cli/xcode). | | Expo config plugin | `@bugsee/react-native` in the `plugins` of `app.json`. | Writes all of the above on `expo prebuild`. React Native's dSYMs are opt-in, with `symbolicateReactNativeFrameworks`. See [Expo](/sdk/react_native/expo#what-the-plugin-changes). |