Configure User Feedback

Learn about User Feedback configuration fields.

User Feedback configuration controls how the managed feedback form opens, what fields it shows, and how it looks. Set global configuration in SentryOptions.configureUserFeedback to install the User Feedback integration required by SentrySDK.feedback.show() and global shake and screenshot triggers, then override individual form presentations when needed.

Use global configuration for behavior that should apply across your app, such as screenshot triggers, shake gestures, default form text, hooks, and theming. This is also where the SDK installs the User Feedback integration for automatic presentation. With global configuration, the SDK tracks the active managed form and won't present another form from SDK-managed presentation paths while one is already open.

Copied
import Sentry

SentrySDK.start { options in
    options.dsn = "___PUBLIC_DSN___"
    options.configureUserFeedback = { config in
        config.showFormForScreenshots = true
        config.configureForm = { form in
            form.formTitle = "Report Feedback"
            form.submitButtonLabel = "Send Feedback"
        }
    }
}

The following options can be configured in SentryUserFeedbackConfiguration:

OptionTypeDefaultDescription
animationsBooltrueShows animations when presenting and dismissing the form.
useShakeGestureBoolfalseOpens the form when the user shakes the device.
showFormForScreenshotsBoolfalseOpens the form when the user takes a screenshot and attaches that screenshot.
configureFormCallbacknilConfigures the managed form fields and labels.
configureThemeCallbacknilConfigures colors, fonts, and form element outlines.
tags[String: Any]nilSets tags on the feedback event. Values can be strings, numbers, or other serializable objects.

The following hooks let you react to the form lifecycle and submission result:

HookTypeDescription
onFormOpen() -> VoidCalled when the managed feedback form opens.
onFormClose() -> VoidCalled when the managed feedback form closes.
onSubmitSuccess([String: Any]) -> VoidCalled when feedback is successfully submitted through the managed form.
onSubmitError(Error) -> VoidCalled when the form fails validation or another client-side submit error occurs.

onSubmitSuccess receives a dictionary with these keys:

  • message: The feedback message.
  • name: The submitted name, when available.
  • email: The submitted email, when available.
  • attachments: The submitted attachments, when available. The managed form currently supports screenshot attachments.

Use per-presentation configuration when one screen needs different labels, hooks, or theme values. The SDK copies the global configuration, applies your overrides, and uses the result only for that form presentation.

Copied
SentrySDK.feedback.show { config in
    config.configureForm = { form in
        form.formTitle = "Feedback for checkout"
        form.submitButtonLabel = "Send Feedback"
    }
}

Per-presentation configuration doesn't apply to global-only settings. useShakeGesture, showFormForScreenshots, and deprecated widget or custom button settings must be set in options.configureUserFeedback.

Use SentryUserFeedbackFormConfiguration to customize the managed form. The message field is always required. Name and email are optional unless you mark them as required.

OptionTypeDefaultDescription
useSentryUserBooltruePrefills name and email from the current Sentry user when available.
showBrandingBooltrueShows Sentry branding inside the form.
formTitleString"Report a Bug"Title at the top of the form.
messageLabelString"Description"Label for the feedback message field.
messagePlaceholderString"What's the bug? What did you expect?"Placeholder for the feedback message field.
messageTextViewAccessibilityLabelStringmessagePlaceholderAccessibility label for the feedback message field.
isRequiredLabelString"(Required)"Text shown next to required fields.
removeScreenshotButtonLabelString"Remove screenshot"Label for the remove screenshot button.
removeScreenshotButtonAccessibilityLabelStringremoveScreenshotButtonLabelAccessibility label for the remove screenshot button.
isNameRequiredBoolfalseRequires the name field.
showNameBooltrueShows the name field. Ignored when isNameRequired is true.
nameLabelString"Name"Label for the name field.
namePlaceholderString"Your Name"Placeholder for the name field.
nameTextFieldAccessibilityLabelStringnamePlaceholderAccessibility label for the name field.
isEmailRequiredBoolfalseRequires the email field.
showEmailBooltrueShows the email field. Ignored when isEmailRequired is true.
emailLabelString"Email"Label for the email field.
emailPlaceholderString"your.email@example.org"Placeholder for the email field.
emailTextFieldAccessibilityLabelString"Your email address"Accessibility label for the email field.
submitButtonLabelString"Send Bug Report"Label for the submit button.
submitButtonAccessibilityLabelStringsubmitButtonLabelAccessibility label for the submit button.
cancelButtonLabelString"Cancel"Label for cancel buttons.
cancelButtonAccessibilityLabelStringcancelButtonLabelAccessibility label for cancel buttons.
unexpectedErrorTextString"Unexpected client error."Message shown when an unexpected client error happens while submitting.
validationErrorMessageCallbackDefault validation messageReturns the message shown when required fields are missing.
Copied
SentrySDK.start { options in
    options.dsn = "___PUBLIC_DSN___"
    options.configureUserFeedback = { config in
        config.configureForm = { form in
            form.formTitle = "Tell us what happened"
            form.messageLabel = "What happened?"
            form.isEmailRequired = true
            form.useSentryUser = false
        }
    }
}

Use SentryUserFeedbackThemeConfiguration to customize colors, fonts, and form element outlines. Use dynamic UIColor values when you need different light and dark mode colors. The SDK applies default theme values when you don't override them.

OptionDescription
fontFamilyFont family for form text.
foregroundForeground text color.
backgroundForm background color.
submitForegroundForeground color for the submit button.
submitBackgroundBackground color for the submit button.
buttonForegroundForeground color for cancel and screenshot buttons.
buttonBackgroundBackground color for cancel and screenshot buttons.
errorColorColor for validation and error UI.
outlineStyleOutline style for inputs and buttons.
inputBackgroundBackground color for text inputs.
inputForegroundForeground color for text inputs.
Copied
SentrySDK.start { options in
    options.dsn = "___PUBLIC_DSN___"
    options.configureUserFeedback = { config in
        config.configureTheme = { theme in
            theme.background = UIColor { traits in
                traits.userInterfaceStyle == .dark ? .darkGray : .yellow
            }
            theme.submitBackground = .systemPurple
        }
    }
}

configureDarkTheme is deprecated. Use dynamic UIColor values in configureTheme instead.

The Sentry-managed User Feedback widget and the SDK-installed custom button path are deprecated and will be removed in v10.

Deprecated APIs and configuration include:

  • SentrySDK.feedback.showWidget() and hideWidget()
  • SentryUserFeedbackConfiguration.configureWidget
  • SentryUserFeedbackWidgetConfiguration
  • SentryUserFeedbackConfiguration.customButton
  • SentryUserFeedbackConfiguration.configureDarkTheme

Instead of configuring Sentry to inject or hook up a button, add a button to your own UI and call a presentation API from its action.

Copied
@IBAction private func feedbackButtonTapped(_ sender: UIButton) {
    SentrySDK.feedback.show()
}

If you need exact presenter control, create and present the form yourself:

Copied
@IBAction private func feedbackButtonTapped(_ sender: UIButton) {
    let form = SentrySDK.FeedbackForm()
    present(form, animated: true)
}

If you build the entire feedback UI yourself, create a SentryFeedback object and send it with SentrySDK.capture(feedback:). For an example, see User Feedback API.

Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").