|
| 1 | +--- |
| 2 | +title: Configure User Feedback |
| 3 | +sidebar_order: 6900 |
| 4 | +description: "Learn about general User Feedback configuration fields." |
| 5 | +--- |
| 6 | + |
| 7 | +<PlatformSection notSupported={["apple.macos", "apple.tvos", "apple.watchos", "apple.visionos"]}> |
| 8 | + |
| 9 | +## User Feedback Widget |
| 10 | + |
| 11 | +The User Feedback Widget offers many customization options, and if the available options are insufficient, you can [use your own UI](#bring-your-own-widget). |
| 12 | + |
| 13 | +### General |
| 14 | + |
| 15 | +The following options can be configured for the integration in `SentryUserFeedbackConfiguration`: |
| 16 | + |
| 17 | +| Option | Type | Default | Description | |
| 18 | +| ------------------------ | --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 19 | +| `animations` | `Bool` | `true` | Whether or not to show animations, like for presenting and dismissing the form. | |
| 20 | +| `useShakeGesture` | `Bool` | `false` | Use a shake gesture to display the form. | |
| 21 | +| `showFormForScreenshots` | `Bool` | `false` | Any time a user takes a screenshot, bring up the form with the screenshot attached. | |
| 22 | +| `tags` | `[String: Any]` | `nil` | Tags to set on the feedback event. This is a dictionary where keys are strings and values can be different data types such as `NSNumber`, `NSString`, etc. | |
| 23 | + |
| 24 | +Some hooks are available so you can react to the user opening and closing the form, when the user successfully submits the form or when there is an error: |
| 25 | + |
| 26 | +| Hook | Type | Description | |
| 27 | +| ----------------- | ------------------------- | ------------------------------------------------------------------------ | |
| 28 | +| `onFormOpen` | `() -> Void` | Called when the feedback form is opened. | |
| 29 | +| `onFormClose` | `() -> Void` | Called when the feedback form is closed. | |
| 30 | +| `onSubmitSuccess` | `([String: Any]) -> Void` | Called when feedback is successfully submitted via the prepared form. | |
| 31 | +| `onSubmitError` | `(Error) -> Void` | Called when there is an error submitting feedback via the prepared form. | |
| 32 | + |
| 33 | +`onSubmitSuccess` provides a dictionary with the following keys: |
| 34 | + |
| 35 | +- `message`: The message the user entered in the feedback form. |
| 36 | +- `name`: The name the user entered in the feedback form. |
| 37 | +- `email`: The email the user entered in the feedback form. |
| 38 | +- `attachments`: An array of attachments to be included with the feedback; currently only one screenshot is supported. |
| 39 | + |
| 40 | +Example: |
| 41 | + |
| 42 | +```swift |
| 43 | +SentrySDK.start { options in |
| 44 | + options.showFormForScreenshots = true |
| 45 | + options.configureUserFeedback { config in |
| 46 | + config.onSubmitSuccess = { data in |
| 47 | + print("Feedback submitted successfully from \(data["name"]) at \(data["email"]): \(data["message"])") |
| 48 | + } |
| 49 | + } |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +### Widget |
| 54 | + |
| 55 | +The following options can be configured for the integration in `SentryUserFeedbackWidgetConfiguration`: |
| 56 | + |
| 57 | +| Option | Type | Default | Description | |
| 58 | +| ---------------- | ------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 59 | +| `location` | `[NSDirectionalRectEdge]` | `[.bottom, .trailing]` | The location of the widget on the screen. | |
| 60 | +| `autoInject` | `Bool` | `true` | Injects the Feedback widget into the application when the integration is added. Set `autoInject: false` if you want to call `feedback.attachTo()` or `feedback.openDialog()` directly, or only want to show the widget on certain views. | |
| 61 | +| `windowLevel` | `UIWindow.Level` | `UIWindow.Level.normal + 1` | The window level of the widget. | |
| 62 | +| `showIcon` | `Bool` | `true` | Whether to show the widget icon. | |
| 63 | +| `labelText` | `String?` | `"Report a Bug"` | The text of the widget label. If `nil`, then only the icon is shown. It is an error to set both `labelText` to `nil` and `showIcon` to `false`. | |
| 64 | +| `layoutUIOffset` | `UIOffset` | `UIOffset.zero` | The offset of the widget from edge(s) of the screen specified in `location`. | |
| 65 | + |
| 66 | +### Form Configuration |
| 67 | + |
| 68 | +You can customize which form elements are shown, whether they are required, and even prefill some info, in `SentryUserFeedbackFormConfiguration`: |
| 69 | + |
| 70 | +| Option | Type | Default | Description | |
| 71 | +| ----------------------------- | -------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | |
| 72 | +| `showBranding` | `Bool` | `true` | Displays the Sentry logo inside of the form | |
| 73 | +| `formTitle` | `String` | `"Report a Bug"` | The title of the feedback form. | |
| 74 | +| `messageLabel` | `String` | `"Description"` | The label of the feedback description input field. | |
| 75 | +| `messagePlaceholder` | `String` | `"What's the bug? What did you expect?"` | The placeholder in the feedback description input field. | |
| 76 | +| `isRequiredLabel` | `String` | `"(Required)"` | The text to attach to the title label for a required field. | |
| 77 | +| `successMessageText` | `String` | `"Screenshot"` | The label of the screenshot button. | |
| 78 | +| `removeScreenshotButtonLabel` | `String` | `"Remove Screenshot"` | The label of the remove screenshot button. | |
| 79 | +| `isNameRequired` | `Bool` | `false` | Requires the name field on the feedback form to be filled in. | |
| 80 | +| `showName` | `Bool` | `true` | Displays the name field on the feedback form. Ignored if `isNameRequired` is `true`. | |
| 81 | +| `nameLabel` | `String` | `"Name"` | The label next to the name input field. | |
| 82 | +| `namePlaceholder` | `String` | `"Your Name"` | The placeholder in the name input field. | |
| 83 | +| `isEmailRequired` | `Bool` | `false` | Requires the email field on the feedback form to be filled in. | |
| 84 | +| `showEmail` | `Bool` | `true` | Displays the email field on the feedback form. Ignored if `isEmailRequired` is `true`. | |
| 85 | +| `emailLabel` | `String` | `"Email"` | The label next to the email input field. | |
| 86 | +| `emailPlaceholder` | `String` | `"[email protected]"` | The placeholder in the email input field. | |
| 87 | +| `submitButtonLabel` | `String` | `"Send Bug Report"` | The label of the submit button. | |
| 88 | +| `cancelButtonLabel` | `String` | `"Cancel"` | The label of the cancel button. | |
| 89 | +| `useSentryUser` | `Bool` | `true` | Sets the `email` and `name` fields to the corresponding Sentry SDK user fields that were called with `SentrySDK.setUser`. | |
| 90 | +| `isRequiredText` | `String` | `(required)` | The text displayed next to a required field. | |
| 91 | + |
| 92 | +Example: |
| 93 | + |
| 94 | +```swift |
| 95 | +SentrySDK.start { options in |
| 96 | + options.configureUserFeedback { config in |
| 97 | + config.configureForm { form in |
| 98 | + form.isRequiredText = "*" |
| 99 | + form.title = "We want to hear from you!" |
| 100 | + form.useSentryUser = false |
| 101 | + } |
| 102 | + } |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +### Theme Customization |
| 107 | + |
| 108 | +Colors can be customized via the top-level config object, configuring for both light and dark themes. |
| 109 | + |
| 110 | +| Option | Light | Dark | Description | |
| 111 | +| ------------------ | ------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------- | |
| 112 | +| `background` | `rgb(255, 255, 255)` | `rgb(41, 35, 47)` | Background color of the widget and form. | |
| 113 | +| `foreground` | `rgb(43, 34, 51)` | `rgb(235, 230, 239)` | Foreground text color of the widget and form. | |
| 114 | +| `submitForeground` | `rgb(255, 255, 255)` | `rgb(255, 255, 255)` | Foreground color for the form submit button. | |
| 115 | +| `submitBackground` | `rgb(88, 74, 192)` | `rgb(88, 74, 192)` | Background color for the form submit button. | |
| 116 | +| `buttonForeground` | Same as `foreground` | Same as `foreground` | Foreground color for the cancel and screenshot buttons. | |
| 117 | +| `buttonBackground` | `UIColor.clear` | `UIColor.clear` | Background color for the form cancel and screenshot buttons. | |
| 118 | +| `errorColor` | `rgb(223, 51, 56)` | `rgb(245, 84, 89)` | Color used for error-related components. | |
| 119 | +| `inputBackground` | `UIColor.`<br />`secondarySystemBackground` | `UIColor.`<br />`secondarySystemBackground` | Background color for form inputs. | |
| 120 | +| `inputForeground` | `UIColor.darkText` | `UIColor.lightText` | Foreground color for form inputs. | |
| 121 | + |
| 122 | + |
| 123 | +Form element outlines can be configured via the `outlineStyle` property. By default, the color is `rgb(204, 204, 204)`, the width is `0.5`, and the corner radius is `5.0`. |
| 124 | + |
| 125 | +Fonts can be directly customized, but by default they will scale with the user's preferred text size using predefined font styles: |
| 126 | + |
| 127 | +| Option | Default Text Style | Description | |
| 128 | +| ------------ | --------------------------- | --------------------------------------------------------------------------- | |
| 129 | +| `font` | `"UIFontTextStyleCallout"` | The font family to use for form input elements and the widget button label. | |
| 130 | +| `headerFont` | `"UIFontTextStyleTitle1"` | The font family to use for the main header title of the feedback form. | |
| 131 | +| `titleFont` | `"UIFontTextStyleHeadline"` | The font family to use for titles of text fields and buttons in the form. | |
| 132 | + |
| 133 | +You can still configure the `fontFamily` setting and we will request an appropriately scaled font from the system. |
| 134 | + |
| 135 | +Here is an example of customizing only the background color for the light theme using the Feedback constructor configuration: |
| 136 | + |
| 137 | +```swift |
| 138 | +SentrySDK.start { options in |
| 139 | + options.configureUserFeedback { config in |
| 140 | + // configureTheme is used for light themes on iOS versions that support dark mode, and as the sole theme configuration for earlier iOS versions that don't support dark mode |
| 141 | + config.theme { theme in |
| 142 | + theme.background = .init(color: .yellow) |
| 143 | + } |
| 144 | + config.darkTheme { theme in |
| 145 | + theme.background = .init(color: .darkGray) |
| 146 | + } |
| 147 | + } |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +### Accessibility |
| 152 | + |
| 153 | +The Feedback widget is designed to be accessible, with a set of default accessibility labels that can be overriden. The following attributes are set to ensure the widget is accessible: |
| 154 | + |
| 155 | +#### `SentryUserFeedbackWidgetConfiguration` |
| 156 | + |
| 157 | +| Configuration Key | Default Value | |
| 158 | +| -------------------------- | -------------------------------------------------- | |
| 159 | +| `widgetAccessibilityLabel` | `labelText` or, if that is `nil`, `"Report a Bug"` | |
| 160 | + |
| 161 | +#### `SentryUserFeedbackFormConfiguration` |
| 162 | + |
| 163 | +| Configuration Key | Default Value | |
| 164 | +| ------------------------------------------ | ----------------------------- | |
| 165 | +| `messageTextViewAccessibilityLabel` | `messagePlaceholder` | |
| 166 | +| `removeScreenshotButtonAccessibilityLabel` | `removeScreenshotButtonLabel` | |
| 167 | +| `nameTextFieldAccessibilityLabel` | `namePlaceholder` | |
| 168 | +| `emailTextFieldAccessibilityLabel` | `"Your email address"` | |
| 169 | +| `submitButtonAccessibilityLabel` | `submitButtonLabel` | |
| 170 | +| `cancelButtonAccessibilityLabel` | `cancelButtonLabel` | |
| 171 | + |
| 172 | +Example: |
| 173 | + |
| 174 | +```swift |
| 175 | +SentrySDK.start { options in |
| 176 | + options.configureUserFeedback { config in |
| 177 | + config.configureWidget { widget in |
| 178 | + widget.widgetAccessibilityLabel = "Report an Issue" // default: "Report a Bug" |
| 179 | + } |
| 180 | + config.configureForm { form in |
| 181 | + form.messageTextViewAccessibilityLabel = "What happened?" // default: "What's the bug? What did you expect?" |
| 182 | + } |
| 183 | + } |
| 184 | +} |
| 185 | +``` |
| 186 | + |
| 187 | +### Bring Your Own Widget |
| 188 | + |
| 189 | +You can also use your own UI components to gather feedback and pass the feedback data object to the `SentrySDK.capture(feedback: SentryFeedback)` function. |
| 190 | + |
| 191 | +```swift |
| 192 | +SentrySDK.capture(feedback: .init( |
| 193 | + message: "This is an example feedback", // required |
| 194 | + name: "Jane Doe", // optional |
| 195 | + email: "[email protected]", // optional |
| 196 | + source: .custom, |
| 197 | + screenshot: somePngImageData // optional |
| 198 | +)); |
| 199 | +``` |
| 200 | + |
| 201 | +</PlatformSection> |
0 commit comments