# User Interaction Instrumentation | Sentry for React Native

The UI instrumentation captures transactions and adds breadcrumbs for touch interactions. Gesture support using React Native Gesture Handler, is also available with the `sentryTraceGesture` wrapper.

## [Touch Events](https://docs.sentry.io/platforms/react-native/tracing/instrumentation/user-interaction-instrumentation.md#touch-events)

Transaction names are composed from a combination of displayed screen names, (for example, `LoginScreen`), and the labels of the element users interacted with, (for example, `login_button`).

To capture UI transactions, you have to first set up [routing instrumentation](https://docs.sentry.io/platforms/react-native/tracing/instrumentation/automatic-instrumentation.md#enable-routing-instrumentation).

UI instrumentation tracing is disabled by default, but you can enable it by setting the `enableUserInteractionTracing` options to `true` and wrapping your root component:

```javascript
import * as Sentry from "@sentry/react-native";


const navigationIntegration = Sentry.reactNavigationIntegration(); // Or any other navigation integration


Sentry.init({
  dsn: "___PUBLIC_DSN___",

  enableUserInteractionTracing: true,
  tracesSampleRate: 1.0,
  integrations: [navigationIntegration],

});

const App = () => <View>Your App</View>;

export default Sentry.wrap(App);
```

The label by which UI elements are identified is set by the `labelName` option in `Sentry.wrap`. If no value is supplied, `sentry-label` will be used instead. If an element can't be identified, the transaction won't be captured.

```javascript
export default Sentry.wrap(App, {

  touchEventBoundaryProps: { labelName: "my-label" },

});
```

### [Adding Custom Attributes to User Interaction Spans](https://docs.sentry.io/platforms/react-native/tracing/instrumentation/user-interaction-instrumentation.md#adding-custom-attributes-to-user-interaction-spans)

The `sentry-span-attributes` prop is experimental and may change in future releases.

You can attach custom attributes to user interaction spans by passing the `sentry-span-attributes` prop to your components. This is useful for adding contextual information like user type, cart value, or feature flags that help you understand user behavior in performance monitoring.

The `sentry-span-attributes` prop accepts an object with string keys and values that are strings, numbers, booleans, or arrays. These attributes will be attached to the user interaction span created when the component is interacted with.

```javascript
<Pressable
  sentry-label="checkout"
  sentry-span-attributes={{
    "user.type": userType,
    "cart.value": cartValue,
    "feature.enabled": true,
  }}
  onPress={handleCheckout}
>
  <Text>Checkout</Text>
</Pressable>;
```

The SDK will traverse the component tree to find the `sentry-span-attributes` prop, so you can attach it to parent components if needed. The attributes work alongside `sentry-label` and will be included in the user interaction span.

If the UI transaction idled, but didn't have any child spans, it'll be dropped.

Because transactions are automatically bound to scope, you can create child spans using [custom instrumentation](https://docs.sentry.io/platforms/react-native/tracing/instrumentation/custom-instrumentation.md#retrieve-a-transaction). Note, that the `idleTimeoout` for running UI transactions defaults to `1000` milliseconds (one second).

## [Gesture Events](https://docs.sentry.io/platforms/react-native/tracing/instrumentation/user-interaction-instrumentation.md#gesture-events)

To create UI transactions from React Native Gesture Handler, you need to wrap individual gestures using `sentryTraceGesture`. This will also automatically create breadcrumbs. The wrapper `sentryTraceGesture(label, gesture)` accepts `string` labels that uniquely identify the gesture in a screen as well as the gesture object being wrapped.

Only [RNGH API v2](https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/gesture/) is supported.

```javascript
import React from "react";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import { sentryTraceGesture } from "@sentry/react-native";

export const GesturesTracingScreen = () => {
  const pinch = Gesture.Pinch();
  const longPress = Gesture.LongPress();

  const gesture = Gesture.Race(

    sentryTraceGesture("pinch-to-zoom", pinch),
    sentryTraceGesture("long-press-to-cancel", longPress),

  );

  return <GestureDetector gesture={gesture}>// ...</GestureDetector>;
};
```
