From ca709cfc58289409445038e4c813029818566d05 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 13 May 2026 14:47:53 +0200 Subject: [PATCH 1/6] docs(react-native): Document touch breadcrumb label improvements - Document automatic `sentry-label` injection via `autoInjectSentryLabel` - Document runtime text extraction from children (`extractTextFromChildren`) - Document interaction with Session Replay masking (`maskAllText`, `Sentry.Mask`) - Update label priority chain to include text extraction and masking notes Co-Authored-By: Claude Opus 4.6 --- .../configuration/touchevents.mdx | 74 ++++++++++++++++++- .../integrations/component-names.mdx | 38 ++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index 2c0b186b15cd3..ee3bf869976ce 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -58,11 +58,12 @@ For each component in the touch path, the SDK extracts a **label** and a **name* The **label** is determined by the first available value from: -1. `sentry-label` prop +1. `sentry-label` prop (skipped when masked — see [Interaction with Session Replay Masking](#interaction-with-session-replay-masking)) 2. Custom `labelName` prop (if configured on the boundary) 3. `accessibilityLabel` prop 4. `aria-label` prop 5. `testID` prop +6. Text extracted from children (skipped when masked — see [Automatic Text Extraction from Children](#automatic-text-extraction-from-children)) The **name** comes from the Babel plugin annotation (`data-sentry-component`) or `displayName`. See [Component Names](/platforms/react-native/integrations/component-names/) for details. @@ -84,6 +85,77 @@ You don't have to worry about Typescript errors when passing the `sentry-label` +### Automatic `sentry-label` Injection + +When [Component Names](/platforms/react-native/integrations/component-names/) are enabled (`annotateReactComponents` option), the Babel plugin automatically injects `sentry-label` props from static text content at build time. This means components like: + +```javascript +function SaveButton() { + return ( + + Save workout + + ); +} +``` + +will automatically have a `sentry-label="Save workout"` prop added to `Pressable` during the build, without any manual annotation. The injected label: + +- Is derived from static string children only (dynamic expressions are skipped) +- Is capped at 64 characters +- Does not override an existing `sentry-label` prop + +To disable automatic injection while keeping component name annotations: + +```javascript {filename:metro.config.js} +module.exports = withSentryConfig(config, { + annotateReactComponents: { autoInjectSentryLabel: false }, +}); +``` + +### Automatic Text Extraction from Children + +When no label is found from props (steps 1–5 above), the SDK attempts to extract text from the touched component's children at runtime. For example, if you touch a button: + +```javascript + + Add to cart + +``` + +The breadcrumb label will automatically be `"Add to cart"` without needing any props. + +Text extraction has the following limits: +- Traverses up to **3 levels** deep into the component tree +- Visits up to **5 sibling** nodes at each level +- Truncates text at **64 characters** + +To disable runtime text extraction: + +```javascript + + + +``` + +### Interaction with Session Replay Masking + +To prevent masked content from leaking into breadcrumbs, the SDK respects [Session Replay](/platforms/react-native/session-replay/) masking boundaries: + +- When `maskAllText` is enabled on `mobileReplayIntegration` (the default), `sentry-label` and text extraction from children are both skipped, since they may contain user-visible text content. +- When the touched element is inside a `Sentry.Mask` boundary, `sentry-label` and text extraction are skipped for that element. +- Developer-provided labels (`accessibilityLabel`, `aria-label`, `testID`) are never affected by masking. + +To enable `sentry-label` and text extraction alongside Session Replay, set `maskAllText: false`: + +```javascript +Sentry.init({ + integrations: [ + Sentry.mobileReplayIntegration({ maskAllText: false }), + ], +}); +``` + ## Options You can pass specific options to configure the boundary either as props to the `Sentry.TouchEventBoundary` component or as the second argument to the `Sentry.withTouchEventBoundary` higher-order component (HOC). diff --git a/docs/platforms/react-native/integrations/component-names.mdx b/docs/platforms/react-native/integrations/component-names.mdx index 09f520e1e0583..02ef15147130d 100644 --- a/docs/platforms/react-native/integrations/component-names.mdx +++ b/docs/platforms/react-native/integrations/component-names.mdx @@ -71,6 +71,44 @@ Here's what the resulting node would look like if your bundler had applied the p The Sentry browser SDK will pick off the value from these `data` attributes and collect them when your components are interacted with. +## Automatic `sentry-label` Injection + +When component name capturing is enabled, the Babel plugin also automatically injects `sentry-label` props derived from static text content in your JSX. This provides meaningful labels for [touch event breadcrumbs](/platforms/react-native/configuration/touchevents/) without any manual annotation. + +For example, this component: + +```javascript +function SaveButton() { + return ( + + Save workout + + ); +} +``` + +will have `sentry-label="Save workout"` added to `Pressable` at build time. The injection: + +- Only uses static string children (dynamic expressions like `{variable}` are skipped) +- Caps the label at 64 characters +- Skips components that already have an explicit `sentry-label` prop +- Recognizes `Text` components by default, with support for custom text components via `textComponentNames` + +To disable automatic label injection while keeping component name annotations: + +```javascript {tabTitle:React Native} {filename:metro.config.js} +const config = getDefaultConfig(__dirname); +module.exports = withSentryConfig(config, { + annotateReactComponents: { autoInjectSentryLabel: false }, +}); +``` + +```javascript {tabTitle:Expo} {filename:metro.config.js} +const config = getSentryExpoConfig(__dirname, { + annotateReactComponents: { autoInjectSentryLabel: false }, +}); +``` + ## Options By default only components located in your project (outside of `node_modules`) are annotated. To avoid annotating other components, use the `ignoredComponents` option. The ignored components won't have `data-sentry-*` annotations added. From 3d6ec2d56c4e81e75d0981483837118e048a7f04 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 13 May 2026 14:53:28 +0200 Subject: [PATCH 2/6] fix: Address review feedback - Promote subsections to h2 headings for better page structure - Add version availability alerts (8.12.0) - Add extractTextFromChildren to Options section - Add full import/config in code examples for consistency - Trim component-names.mdx duplication, link to touchevents for details - Remove undocumented textComponentNames mention Co-Authored-By: Claude Opus 4.6 --- .../configuration/touchevents.mdx | 46 ++++++++++++++----- .../integrations/component-names.mdx | 9 +--- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index ee3bf869976ce..53242a79a185b 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -85,7 +85,13 @@ You don't have to worry about Typescript errors when passing the `sentry-label` -### Automatic `sentry-label` Injection +## Automatic `sentry-label` Injection + + + +Available in SDK version `8.12.0` and above. + + When [Component Names](/platforms/react-native/integrations/component-names/) are enabled (`annotateReactComponents` option), the Babel plugin automatically injects `sentry-label` props from static text content at build time. This means components like: @@ -107,13 +113,33 @@ will automatically have a `sentry-label="Save workout"` prop added to `Pressable To disable automatic injection while keeping component name annotations: -```javascript {filename:metro.config.js} +```javascript {tabTitle:React Native} {filename:metro.config.js} +const { getDefaultConfig } = require("@react-native/metro-config"); +const { withSentryConfig } = require('@sentry/react-native/metro'); + +const config = getDefaultConfig(__dirname); module.exports = withSentryConfig(config, { annotateReactComponents: { autoInjectSentryLabel: false }, }); ``` -### Automatic Text Extraction from Children +```javascript {tabTitle:Expo} {filename:metro.config.js} +const { getSentryExpoConfig } = require("@sentry/react-native/metro"); + +const config = getSentryExpoConfig(__dirname, { + annotateReactComponents: { autoInjectSentryLabel: false }, +}); +``` + +See [Component Names — Automatic `sentry-label` Injection](/platforms/react-native/integrations/component-names/#automatic-sentry-label-injection) for more details. + +## Automatic Text Extraction from Children + + + +Available in SDK version `8.12.0` and above. + + When no label is found from props (steps 1–5 above), the SDK attempts to extract text from the touched component's children at runtime. For example, if you touch a button: @@ -130,15 +156,9 @@ Text extraction has the following limits: - Visits up to **5 sibling** nodes at each level - Truncates text at **64 characters** -To disable runtime text extraction: - -```javascript - - - -``` +To disable runtime text extraction, set `extractTextFromChildren` to `false` (see [Options](#options)). -### Interaction with Session Replay Masking +## Interaction with Session Replay Masking To prevent masked content from leaking into breadcrumbs, the SDK respects [Session Replay](/platforms/react-native/session-replay/) masking boundaries: @@ -202,6 +222,10 @@ _Array<string | RegExp>, Accepts strings and regular expressions_. Component _String_. The name of a custom prop to look for when determining the label of a component. Takes priority over the automatic `accessibilityLabel`, `aria-label`, and `testID` fallbacks. +`extractTextFromChildren` + +_boolean, default: true_. When enabled, the SDK extracts text from child components as a label fallback when no explicit label prop is set. Automatically disabled when Session Replay's `maskAllText` is enabled. See [Automatic Text Extraction from Children](#automatic-text-extraction-from-children). + ## Minified Names in Production When bundling for production, React Native will minify class and function names to reduce the bundle size. This means that **you won't get the full original component names in your touch event breadcrumbs** and instead you will see minified names. Check out our [troubleshooting guide for minified production bundles](/platforms/react-native/troubleshooting/#minified-names-in-production) documentation to solve this. diff --git a/docs/platforms/react-native/integrations/component-names.mdx b/docs/platforms/react-native/integrations/component-names.mdx index 02ef15147130d..c325f1c6b4d50 100644 --- a/docs/platforms/react-native/integrations/component-names.mdx +++ b/docs/platforms/react-native/integrations/component-names.mdx @@ -73,7 +73,7 @@ The Sentry browser SDK will pick off the value from these `data` attributes and ## Automatic `sentry-label` Injection -When component name capturing is enabled, the Babel plugin also automatically injects `sentry-label` props derived from static text content in your JSX. This provides meaningful labels for [touch event breadcrumbs](/platforms/react-native/configuration/touchevents/) without any manual annotation. +When component name capturing is enabled, the Babel plugin also automatically injects `sentry-label` props derived from static text content in your JSX. This provides meaningful labels for [touch event breadcrumbs](/platforms/react-native/configuration/touchevents/#automatic-sentry-label-injection) without any manual annotation. For example, this component: @@ -87,12 +87,7 @@ function SaveButton() { } ``` -will have `sentry-label="Save workout"` added to `Pressable` at build time. The injection: - -- Only uses static string children (dynamic expressions like `{variable}` are skipped) -- Caps the label at 64 characters -- Skips components that already have an explicit `sentry-label` prop -- Recognizes `Text` components by default, with support for custom text components via `textComponentNames` +will have `sentry-label="Save workout"` added to `Pressable` at build time. The injection only uses static string children, caps the label at 64 characters, and skips components that already have an explicit `sentry-label` prop. To disable automatic label injection while keeping component name annotations: From c9871dd83984365cce1a5480726f54d3f226071e Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 13 May 2026 15:02:50 +0200 Subject: [PATCH 3/6] fix: Address review feedback round 2 - Add version alert to component-names.mdx sentry-label section - Add imports to component-names.mdx disable examples - Add labelName to unaffected labels in masking section - Clarify build-time vs runtime extraction relationship Co-Authored-By: Claude Opus 4.6 --- .../react-native/configuration/touchevents.mdx | 4 ++-- .../react-native/integrations/component-names.mdx | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index 53242a79a185b..d39d14a69e4fd 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -141,7 +141,7 @@ Available in SDK version `8.12.0` and above. -When no label is found from props (steps 1–5 above), the SDK attempts to extract text from the touched component's children at runtime. For example, if you touch a button: +When no label is found from props (steps 1–5 above), the SDK attempts to extract text from the touched component's children at runtime. This complements the [build-time injection](#automatic-sentry-label-injection) — it handles dynamic text, components not processed by the Babel plugin, or cases where `annotateReactComponents` is not enabled. For example, if you touch a button: ```javascript @@ -164,7 +164,7 @@ To prevent masked content from leaking into breadcrumbs, the SDK respects [Sessi - When `maskAllText` is enabled on `mobileReplayIntegration` (the default), `sentry-label` and text extraction from children are both skipped, since they may contain user-visible text content. - When the touched element is inside a `Sentry.Mask` boundary, `sentry-label` and text extraction are skipped for that element. -- Developer-provided labels (`accessibilityLabel`, `aria-label`, `testID`) are never affected by masking. +- Developer-provided labels (custom `labelName`, `accessibilityLabel`, `aria-label`, `testID`) are never affected by masking. To enable `sentry-label` and text extraction alongside Session Replay, set `maskAllText: false`: diff --git a/docs/platforms/react-native/integrations/component-names.mdx b/docs/platforms/react-native/integrations/component-names.mdx index c325f1c6b4d50..70c1e9c68f7f4 100644 --- a/docs/platforms/react-native/integrations/component-names.mdx +++ b/docs/platforms/react-native/integrations/component-names.mdx @@ -73,6 +73,12 @@ The Sentry browser SDK will pick off the value from these `data` attributes and ## Automatic `sentry-label` Injection + + +Available in SDK version `8.12.0` and above. + + + When component name capturing is enabled, the Babel plugin also automatically injects `sentry-label` props derived from static text content in your JSX. This provides meaningful labels for [touch event breadcrumbs](/platforms/react-native/configuration/touchevents/#automatic-sentry-label-injection) without any manual annotation. For example, this component: @@ -92,6 +98,9 @@ will have `sentry-label="Save workout"` added to `Pressable` at build time. The To disable automatic label injection while keeping component name annotations: ```javascript {tabTitle:React Native} {filename:metro.config.js} +const { getDefaultConfig } = require("@react-native/metro-config"); +const { withSentryConfig } = require('@sentry/react-native/metro'); + const config = getDefaultConfig(__dirname); module.exports = withSentryConfig(config, { annotateReactComponents: { autoInjectSentryLabel: false }, @@ -99,6 +108,8 @@ module.exports = withSentryConfig(config, { ``` ```javascript {tabTitle:Expo} {filename:metro.config.js} +const { getSentryExpoConfig } = require("@sentry/react-native/metro"); + const config = getSentryExpoConfig(__dirname, { annotateReactComponents: { autoInjectSentryLabel: false }, }); From 58ba7056f99554ed2a2a95b31dc94b4ae18f41ee Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 13 May 2026 15:08:50 +0200 Subject: [PATCH 4/6] fix: Remove clutter from label priority list and deduplicate sections - Remove "(skipped when masked)" notes from priority chain - Replace duplicated autoInjectSentryLabel section with brief mention + link Co-Authored-By: Claude Opus 4.6 --- .../configuration/touchevents.mdx | 50 ++----------------- 1 file changed, 4 insertions(+), 46 deletions(-) diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index d39d14a69e4fd..19e3f34cec5ca 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -58,12 +58,12 @@ For each component in the touch path, the SDK extracts a **label** and a **name* The **label** is determined by the first available value from: -1. `sentry-label` prop (skipped when masked — see [Interaction with Session Replay Masking](#interaction-with-session-replay-masking)) +1. `sentry-label` prop 2. Custom `labelName` prop (if configured on the boundary) 3. `accessibilityLabel` prop 4. `aria-label` prop 5. `testID` prop -6. Text extracted from children (skipped when masked — see [Automatic Text Extraction from Children](#automatic-text-extraction-from-children)) +6. Text extracted from children The **name** comes from the Babel plugin annotation (`data-sentry-component`) or `displayName`. See [Component Names](/platforms/react-native/integrations/component-names/) for details. @@ -87,51 +87,9 @@ You don't have to worry about Typescript errors when passing the `sentry-label` ## Automatic `sentry-label` Injection - - -Available in SDK version `8.12.0` and above. - - - -When [Component Names](/platforms/react-native/integrations/component-names/) are enabled (`annotateReactComponents` option), the Babel plugin automatically injects `sentry-label` props from static text content at build time. This means components like: - -```javascript -function SaveButton() { - return ( - - Save workout - - ); -} -``` - -will automatically have a `sentry-label="Save workout"` prop added to `Pressable` during the build, without any manual annotation. The injected label: - -- Is derived from static string children only (dynamic expressions are skipped) -- Is capped at 64 characters -- Does not override an existing `sentry-label` prop - -To disable automatic injection while keeping component name annotations: - -```javascript {tabTitle:React Native} {filename:metro.config.js} -const { getDefaultConfig } = require("@react-native/metro-config"); -const { withSentryConfig } = require('@sentry/react-native/metro'); - -const config = getDefaultConfig(__dirname); -module.exports = withSentryConfig(config, { - annotateReactComponents: { autoInjectSentryLabel: false }, -}); -``` - -```javascript {tabTitle:Expo} {filename:metro.config.js} -const { getSentryExpoConfig } = require("@sentry/react-native/metro"); - -const config = getSentryExpoConfig(__dirname, { - annotateReactComponents: { autoInjectSentryLabel: false }, -}); -``` +When [Component Names](/platforms/react-native/integrations/component-names/) are enabled (`annotateReactComponents` option), the Babel plugin automatically injects `sentry-label` props from static text content at build time. For example, a `` wrapping `Save workout` will automatically receive `sentry-label="Save workout"` during the build, without any manual annotation. -See [Component Names — Automatic `sentry-label` Injection](/platforms/react-native/integrations/component-names/#automatic-sentry-label-injection) for more details. +See [Component Names — Automatic `sentry-label` Injection](/platforms/react-native/integrations/component-names/#automatic-sentry-label-injection) for configuration details. ## Automatic Text Extraction from Children From 54cce37efbeaaa55191c63f281f606dcd9a6016a Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 13 May 2026 15:10:54 +0200 Subject: [PATCH 5/6] fix: Add version alert to touchevents autoInjectSentryLabel section Co-Authored-By: Claude Opus 4.6 --- docs/platforms/react-native/configuration/touchevents.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index 19e3f34cec5ca..c850a80841f4d 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -87,6 +87,12 @@ You don't have to worry about Typescript errors when passing the `sentry-label` ## Automatic `sentry-label` Injection + + +Available in SDK version `8.12.0` and above. + + + When [Component Names](/platforms/react-native/integrations/component-names/) are enabled (`annotateReactComponents` option), the Babel plugin automatically injects `sentry-label` props from static text content at build time. For example, a `` wrapping `Save workout` will automatically receive `sentry-label="Save workout"` during the build, without any manual annotation. See [Component Names — Automatic `sentry-label` Injection](/platforms/react-native/integrations/component-names/#automatic-sentry-label-injection) for configuration details. From 4c7db08287fcb42b91ee12a1d1d3ffdd9d677d35 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 13 May 2026 15:49:34 +0200 Subject: [PATCH 6/6] fix: Add note about manual sentry-label being skipped when masking is active Co-Authored-By: Claude Opus 4.6 --- docs/platforms/react-native/configuration/touchevents.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index c850a80841f4d..464f38a2c4e53 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -130,6 +130,12 @@ To prevent masked content from leaking into breadcrumbs, the SDK respects [Sessi - When the touched element is inside a `Sentry.Mask` boundary, `sentry-label` and text extraction are skipped for that element. - Developer-provided labels (custom `labelName`, `accessibilityLabel`, `aria-label`, `testID`) are never affected by masking. + + +Currently, both manually set and auto-injected `sentry-label` props are skipped when masking is active, because the SDK cannot distinguish between them at runtime. If you rely on manual `sentry-label` props for tracking, use `accessibilityLabel` or a custom `labelName` instead, which are never affected by masking. + + + To enable `sentry-label` and text extraction alongside Session Replay, set `maskAllText: false`: ```javascript