diff --git a/docs/platforms/react-native/configuration/touchevents.mdx b/docs/platforms/react-native/configuration/touchevents.mdx index 2c0b186b15cd3..464f38a2c4e53 100644 --- a/docs/platforms/react-native/configuration/touchevents.mdx +++ b/docs/platforms/react-native/configuration/touchevents.mdx @@ -63,6 +63,7 @@ The **label** is determined by the first available value from: 3. `accessibilityLabel` prop 4. `aria-label` prop 5. `testID` prop +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. @@ -84,6 +85,67 @@ 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. + +## 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. 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 + + 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, set `extractTextFromChildren` to `false` (see [Options](#options)). + +## 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 (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 +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). @@ -130,6 +192,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 09f520e1e0583..70c1e9c68f7f4 100644 --- a/docs/platforms/react-native/integrations/component-names.mdx +++ b/docs/platforms/react-native/integrations/component-names.mdx @@ -71,6 +71,50 @@ 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 + + + +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: + +```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, 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: + +```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 }, +}); +``` + ## 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.