User Interaction Instrumentation
Learn more about the User Interaction Instrumentation for the Flutter SDK.
(New in version 6.17.0)
Enabling UI instrumentation captures transactions and adds breadcrumbs for a set of different user interactions, which include clicks, long clicks, taps, and so on.
Before diving into the configuration, it's important to understand how user interaction instrumentation behaves:
- The instrumentation sets the transaction name specified in the
key
of theWidget
from thekey
of theWidget
, for examplelogin_button
. - The transaction operation is set to
ui.action.click
. - If the user interaction transaction has reached the idleTimeout, but didn't have any child spans added, it will be dropped.
Before starting, ensure:
- The Sentry Flutter SDK is initialized. Learn more here.
- Performance Monitoring is set up. Learn more here.
Wrap your root widget with SentryWidget
:
Future<void> main() async {
await SentryFlutter.init(
// Configure your options
(options) => options.dsn = 'https://examplePublicKey@o0.ingest.sentry.io/0',
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
If the view doesn't have the key assigned, the transaction and the breadcrumb won't be captured because it can't be uniquely identified. The key value should be unique across the whole application because the transactions are grouped by its name.
ElevatedButton(
key: const Key('my_button_widget'),
onPressed: () {
final activeSpan = Sentry.getSpan();
final childSpan = activeSpan?.startChild('some operation', description: 'some description');
childSpan?.finish();
}, child: const Text('User Interaction Example'),
),
Tap on the button specified in step 2 of the configure section, wait for idleTimeout
seconds (default is 3s) then check the performance page for a new transaction called my_button_widget
.
When a new user interaction occurs while a user interaction transaction is still in progress, the SDK automatically completes the ongoing transaction. This is necessary because only one transaction can be active in the scope at a time.
If the same view is interacted with again (e.g. clicking an ElevatedButton
repeatedly) within the idleTimeout
period then the SDK does the following:
- Resets the idle timer for the transaction.
- Extends the transaction’s duration by the length of the
idleTimeout
.
User interaction tracing is enabled by default. If you wish to opt-out of this feature set the enableUserInteractionTracing
option to false
.
import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
await SentryFlutter.init(
(options) => options.enableUserInteractionTracing = false,
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
User interaction breadcrumbs are enabled by default. If you wish to opt-out of this feature set the enableUserInteractionBreadcrumbs
option to false
.
import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
await SentryFlutter.init(
(options) => options.enableUserInteractionBreadcrumbs = false,
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
By default, breadcrumbs exclude widget labels and text to avoid capturing personally identifiable information (PII). To include these details, set the sendDefaultPii
option to true
.
import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
await SentryFlutter.init(
(options) => options.sendDefaultPii = true,
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
The transaction finishes automatically after it reaches the specified idleTimeout and all of its child spans are finished. The idleTimeoout
defaults to 3000
milliseconds (3 seconds).
You can also disable the idle timeout by setting it to null
, but if you do, you must finish the transaction manually.
To finish the transaction manually, use Sentry.getSpan()
to retrieve the active transaction on the scope:
import 'package:sentry/sentry.dart';
// Finish the transaction manually
final activeTransaction = Sentry.getSpan()
await activeTransaction?.finish();
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").