---
title: "User Feedback"
description: "Learn how to enable User Feedback in your app using the Sentry React Native SDK."
url: https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback/
---

# Set Up User Feedback for Expo

The User Feedback feature allows you to collect user feedback from anywhere inside your application at any time, without needing an error event to occur first.

Note that if you're using a self-hosted Sentry instance, you'll need to be on version 24.4.2 or higher in order to use the full functionality of the User Feedback feature. Lower versions may have limited functionality.

| User Feedback iOS | User Feedback Android |
| ----------------- | --------------------- |
|                   |                       |

## [User Feedback Form](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#user-feedback-form)

The user feedback form allows users to submit feedback from anywhere inside your application.

To collect user feedback from inside your application use the `showFeedbackForm` method.

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

Sentry.wrap(RootComponent);

Sentry.showFeedbackForm();
```

Note that [the root application component must be wrapped with `Sentry.wrap`](https://docs.sentry.io/platforms/react-native.md#wrap-your-app) for the `showFeedbackForm` method to work. The method depends on the React Native `Modal` implementation. It is supported fully in the legacy architecture. For the new architecture (Fabric renderer) it requires React Native `0.71` and up.

To configure the form you can use the `Sentry.feedbackIntegration({})` or add it to your Sentry initialization.

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

Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

  integrations: [
    Sentry.feedbackIntegration({
      // Additional SDK configuration goes in here, for example:
      styles: {
        submitButton: {
          backgroundColor: "#6a1b9a",
        },
      },
      namePlaceholder: "Fullname",
    }),
  ],
});
```

There are many options you can pass to the integration constructor. See the [configuration documentation](https://docs.sentry.io/platforms/react-native/user-feedback/configuration.md) for more details.

### [Shake to Report](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#shake-to-report)

You can enable shake-to-report so that shaking the device opens the Feedback Form. Enable it declaratively via the `feedbackIntegration` option:

```javascript
Sentry.feedbackIntegration({
  enableShakeToReport: true,
});
```

Or control it programmatically:

```javascript
// Start listening for shake gestures to open the feedback form
Sentry.enableFeedbackOnShake();

// Stop listening for shake gestures
Sentry.disableFeedbackOnShake();
```

### [Feedback Form Component](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#feedback-form-component)

You can also integrate the `FeedbackForm` component manually in your app.

```javascript
import { FeedbackForm } from "@sentry/react-native";

<FeedbackForm />;
```

For the full set of options you can pass to the `FeedbackForm` component see the [configuration documentation](https://docs.sentry.io/platforms/react-native/user-feedback/configuration.md).

Note that when the device is offline, the feedback will be stored locally and sent when the device is back online.

### [Opening the Feedback Form Over a Presented Sheet on iOS](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#opening-the-feedback-form-over-a-presented-sheet-on-ios)

On iOS, `Sentry.showFeedbackForm()`, shake-to-report, and the auto-injected feedback button present the Feedback Form inside a React Native `Modal`. UIKit only allows one presentation per view controller, so when a native-stack screen is already presented as a sheet (`presentation: "formSheet"` or `"modal"` with `@react-navigation/native-stack`), UIKit refuses the second presentation and the form doesn't appear. Android is unaffected.

To collect feedback while such a sheet is open, render the [`FeedbackForm`](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#feedback-form-component) component yourself and control its visibility. On iOS, wrap it in react-native-screens' `FullWindowOverlay` so it draws above the presented sheet:

```jsx
import { useState } from "react";
import { Button, Modal, Platform, StyleSheet, View } from "react-native";
import { FeedbackForm } from "@sentry/react-native";
import { FullWindowOverlay } from "react-native-screens";

function FeedbackButton() {
  const [visible, setVisible] = useState(false);
  const close = () => setVisible(false);

  // Pass the same options you'd give `feedbackIntegration(...)`
  // (formTitle, namePlaceholder, styles, imagePicker, and so on).
  const form = (
    <View style={StyleSheet.absoluteFill}>
      <FeedbackForm onFormClose={close} onFormSubmitted={close} />
    </View>
  );

  return (
    <>
      <Button title="Give feedback" onPress={() => setVisible(true)} />
      {visible &&
        (Platform.OS === "ios" ? (
          <FullWindowOverlay>{form}</FullWindowOverlay>
        ) : (
          <Modal transparent onRequestClose={close}>
            {form}
          </Modal>
        ))}
    </>
  );
}
```

`FullWindowOverlay` requires `react-native-screens`, which is already installed in apps using native-stack navigation.

### [Session Replay](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#session-replay)

The User Feedback Form integrates seamlessly with Session Replay. When the widget is opened, the SDK buffers up to 30 seconds of the user's session. If feedback is submitted, this replay is sent along with the feedback, allowing you to view both the feedback and the user's actions leading up to the feedback submission.

## [User Feedback API](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback.md#user-feedback-api)

The user feedback API allows you to collect user feedback while utilizing your own UI. You can use the same programming language you have in your app to send user feedback. In this case, the SDK creates the HTTP request so you don't have to deal with posting data via HTTP.

Sentry pairs the feedback with the original event, giving you additional insight into issues. Sentry needs the `eventId` to be able to associate the user feedback to the corresponding event. For example, to get the `eventId`, you can use [`beforeSend`](https://docs.sentry.io/platforms/react-native/guides/expo/configuration/options.md#before-send)or the return value of the method capturing an event.

```typescript
import * as Sentry from "@sentry/react-native";
import { SendFeedbackParams } from "@sentry/react-native";

const sentryId = Sentry.captureMessage("My Message");
// OR: const sentryId = Sentry.lastEventId();

const userFeedback: SendFeedbackParams = {
  name: "John Doe",
  email: "john@doe.com",
  message: "Hello World!",
  associatedEventId: eventId, // Optional
};

Sentry.captureFeedback(userFeedback);
```

You can also attach further data to the feedback event by passing a hint as a second argument. This is similar to other `capture` methods:

```javascript
Sentry.captureFeedback(
  { message: "I really like your App, thanks!" },
  {
    captureContext: {
      tags: { key: "value" },
    },
    attachments: [
      {
        filename: "hello.txt",
        data: "Hello, World!",
      },
    ],
  },
);
```

## Pages in this section

- [Configuration](https://docs.sentry.io/platforms/react-native/guides/expo/user-feedback/configuration.md)
