sentry-flutter-sdk
All Skills > SDK Setup > Flutter SDK
Sentry Flutter SDK
Opinionated wizard that scans your Flutter or Dart project and guides you through complete Sentry setup — error monitoring, tracing, session replay, logging, profiling, and ecosystem integrations.
Invoke This Skill When
- User asks to "add Sentry to Flutter" or "set up Sentry" in a Flutter or Dart app
- User wants error monitoring, tracing, profiling, session replay, or logging in Flutter
- User mentions
sentry_flutter,sentry_dart, mobile error tracking, or Sentry for Flutter - User wants to monitor native crashes, ANRs, or app hangs on iOS/Android
Note: SDK versions and APIs below reflect
sentry_flutter≥9.14.0 (current stable, February 2026). Always verify against docs.sentry.io/platforms/flutter/ before implementing.
Phase 1: Detect
Run these commands to understand the project before making any recommendations:
# Detect Flutter project type and existing Sentry
cat pubspec.yaml | grep -E '(sentry|flutter|dart)'
# Check SDK version
cat pubspec.yaml | grep -A2 'environment:'
# Check for existing Sentry initialization
grep -r "SentryFlutter.init\|Sentry.init" lib/ 2>/dev/null | head -5
# Detect navigation library
grep -E '(go_router|auto_route|get:|beamer|routemaster)' pubspec.yaml
# Detect HTTP client
grep -E '(dio:|http:|chopper:)' pubspec.yaml
# Detect database packages
grep -E '(sqflite|drift|hive|isar|floor)' pubspec.yaml
# Detect state management (for integration patterns)
grep -E '(flutter_bloc|riverpod|provider:|get:)' pubspec.yaml
# Detect GraphQL
grep -E '(graphql|ferry|gql)' pubspec.yaml
# Detect Firebase
grep -E '(firebase_core|supabase)' pubspec.yaml
# Detect backend for cross-link
ls ../backend/ ../server/ ../api/ 2>/dev/null
find .. -maxdepth 3 \( -name "go.mod" -o -name "requirements.txt" -o -name "Gemfile" -o -name "*.csproj" \) 2>/dev/null | grep -v flutter | head -10
# Detect platform targets
ls android/ ios/ macos/ linux/ windows/ web/ 2>/dev/null
What to determine:
| Question | Impact |
|---|---|
sentry_flutter already in pubspec.yaml? |
Skip install, jump to feature config |
Dart SDK >=3.5? |
Required for sentry_flutter ≥9.0.0 |
go_router or auto_route present? |
Use SentryNavigatorObserver — specific patterns apply |
dio present? |
Recommend sentry_dio integration |
sqflite, drift, hive, isar present? |
Recommend matching sentry_* DB package |
Has android/ and ios/ directories? |
Full mobile feature set available |
Has web/ directory only? |
Session Replay and Profiling unavailable |
Has macos/ directory? |
Profiling available (alpha) |
| Backend directory detected? | Trigger Phase 4 cross-link |
Phase 2: Recommend
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage — always set up these):
- ✅ Error Monitoring — captures Dart exceptions, Flutter framework errors, and native crashes (iOS + Android)
- ✅ Tracing — auto-instruments navigation, app start, network requests, and UI interactions
- ✅ Session Replay — captures widget tree screenshots for debugging (iOS + Android only)
Optional (enhanced observability):
- ⚡ Profiling — CPU profiling; iOS and macOS only (alpha)
- ⚡ Logging — structured logs via
Sentry.logger.*andsentry_loggingintegration - ⚡ Metrics — counters, gauges, distributions (open beta, SDK ≥9.11.0)
Platform limitations — be upfront:
| Feature | Platforms | Notes |
|---|---|---|
| Session Replay | iOS, Android | Not available on macOS, Linux, Windows, Web |
| Profiling | iOS, macOS | Alpha status; not available on Android, Linux, Windows, Web |
| Native crashes | iOS, Android, macOS | NDK/signal handling; Linux/Windows/Web: Dart exceptions only |
| App Start metrics | iOS, Android | Not available on desktop/web |
| Slow/frozen frames | iOS, Android, macOS | Not available on Linux, Windows, Web |
| Crons | N/A | Not available in the Flutter/Dart SDK |
Propose: "For your Flutter app targeting iOS/Android, I recommend Error Monitoring + Tracing + Session Replay. Want me to also add Logging and Profiling (iOS/macOS alpha)?"
Phase 3: Guide
Determine Your Setup Path
| Project type | Recommended setup |
|---|---|
| Any Flutter app | Wizard CLI (handles pubspec, init, symbol upload) |
| Manual preferred | Path B below — pubspec.yaml + main.dart |
| Dart-only (CLI, server) | Path C below — pure sentry package |
Path A: Wizard CLI (Recommended)
You need to run this yourself — the wizard opens a browser for login and requires interactive input that the agent can't handle. Copy-paste into your terminal:
brew install getsentry/tools/sentry-wizard && sentry-wizard -i flutterIt handles org/project selection, adds
sentry_fluttertopubspec.yaml, updatesmain.dart, configuressentry_dart_pluginfor debug symbol upload, and adds build scripts. Here's what it creates/modifies:
File Action Purpose pubspec.yamlAdds sentry_flutterdependency andsentry:config blockSDK + symbol upload config lib/main.dartWraps main()withSentryFlutter.init()SDK initialization android/app/build.gradleAdds Proguard config reference Android obfuscation support .sentryclircAuth token and org/project config Symbol upload credentials Once it finishes, come back and skip to Verification.
If the user skips the wizard, proceed with Path B (Manual Setup) below.
Path B: Manual — Flutter App
Step 1 — Install
flutter pub add sentry_flutter
Or add to pubspec.yaml manually:
dependencies:
flutter:
sdk: flutter
sentry_flutter: ^9.14.0
Then run:
flutter pub get
Step 2 — Initialize Sentry in lib/main.dart
import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
await SentryFlutter.init(
(options) {
options.dsn = 'YOUR_SENTRY_DSN';
options.sendDefaultPii = true;
// Tracing
options.tracesSampleRate = 1.0; // lower to 0.1–0.2 in production
// Profiling (iOS and macOS only — alpha)
options.profilesSampleRate = 1.0;
// Session Replay (iOS and Android only)
options.replay.sessionSampleRate = 0.1;
options.replay.onErrorSampleRate = 1.0;
// Structured Logging (SDK ≥9.5.0)
options.enableLogs = true;
options.environment = const bool.fromEnvironment('dart.vm.product')
? 'production'
: 'development';
},
// REQUIRED: wrap root widget to enable screenshots, replay, user interaction tracing
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
Step 3 — Add Navigation Observer
Add SentryNavigatorObserver to your MaterialApp or CupertinoApp:
import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
navigatorObservers: [
SentryNavigatorObserver(),
],
// Always name your routes for Sentry to track them
routes: {
'/': (context) => HomeScreen(),
'/profile': (context) => ProfileScreen(),
},
);
}
}
For GoRouter:
import 'package:go_router/go_router.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
final GoRouter router = GoRouter(
observers: [SentryNavigatorObserver()],
routes: [
GoRoute(
path: '/',
name: 'home', // name is REQUIRED for Sentry route tracking
builder: (context, state) => const HomeScreen(),
routes: [
GoRoute(
path: 'profile/:id',
name: 'profile', // name is REQUIRED
builder: (context, state) => ProfileScreen(
id: state.pathParameters['id']!,
),
),
],
),
],
);
Step 4 — Configure Debug Symbol Upload
Readable stack traces in Sentry require uploading debug symbols when building with --obfuscate.
Add to pubspec.yaml:
dev_dependencies:
sentry_dart_plugin: ^3.2.1
sentry:
project: YOUR_PROJECT_SLUG
org: YOUR_ORG_SLUG
auth_token: YOUR_AUTH_TOKEN # prefer SENTRY_AUTH_TOKEN env var instead
upload_debug_symbols: true
upload_sources: true
upload_source_maps: true # for Web
Build and upload:
# Android
flutter build apk \
--release \
--obfuscate \
--split-debug-info=build/debug-info \
--extra-gen-snapshot-options=--save-obfuscation-map=build/app/obfuscation.map.json
dart run sentry_dart_plugin
# iOS
flutter build ipa \
--release \
--obfuscate \
--split-debug-info=build/debug-info \
--extra-gen-snapshot-options=--save-obfuscation-map=build/app/obfuscation.map.json
dart run sentry_dart_plugin
# Web
flutter build web --release --source-maps
dart run sentry_dart_plugin
Path C: Manual — Dart-Only (CLI / Server)
# pubspec.yaml
dependencies:
sentry: ^9.14.0
import 'package:sentry/sentry.dart';
Future<void> main() async {
await Sentry.init(
(options) {
options.dsn = 'YOUR_SENTRY_DSN';
options.tracesSampleRate = 1.0;
options.enableLogs = true;
},
appRunner: myApp,
);
}
Quick Reference: Full-Featured SentryFlutter.init()
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
await SentryFlutter.init(
(options) {
options.dsn = 'YOUR_SENTRY_DSN';
options.sendDefaultPii = true;
// Environment — detect release builds via dart.vm.product
options.environment = const bool.fromEnvironment('dart.vm.product')
? 'production'
: 'development';
// Release is auto-set on iOS/Android as "packageName@version+build"
// Override if needed:
// options.release = 'my-app@1.0.0+42';
// Error sampling — reduce to drop a fraction of errors in high-volume production
options.sampleRate = 1.0;
// Tracing — lower to 0.1–0.2 in high-traffic production
options.tracesSampleRate = 1.0;
// Profiling — iOS and macOS only (alpha); relative to tracesSampleRate
options.profilesSampleRate = 1.0;
// Session Replay — iOS and Android only (SDK ≥9.0.0)
options.replay.sessionSampleRate = 0.1; // record 10% of all sessions
options.replay.onErrorSampleRate = 1.0; // always record error sessions
// Privacy defaults — all text and images masked
options.privacy.maskAllText = true;
options.privacy.maskAllImages = true;
// Structured logging (SDK ≥9.5.0)
options.enableLogs = true;
// Attachments
options.attachScreenshot = true; // screenshot on error
options.attachViewHierarchy = true; // widget tree on error
// HTTP client
options.captureFailedRequests = true; // auto-capture HTTP errors
options.maxRequestBodySize = MaxRequestBodySize.small;
// Android specifics
options.anrEnabled = true; // ANR detection
options.enableNdkScopeSync = true; // sync scope to native
options.enableTombstone = false; // Android 12+ tombstone (opt-in)
// Navigation (Time to Full Display — opt-in)
options.enableTimeToFullDisplayTracing = true;
},
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
Navigation: Time to Full Display (TTFD)
TTID (Time to Initial Display) is always enabled. TTFD is opt-in:
// Enable in options:
options.enableTimeToFullDisplayTracing = true;
Then report when your screen has loaded its data:
// Option 1: Widget wrapper (marks TTFD when child first renders)
SentryDisplayWidget(child: MyWidget())
// Option 2: Manual API call (after async data loads)
await _loadData();
SentryFlutter.currentDisplay()?.reportFullyDisplayed();
For Each Agreed Feature
Walk through features one at a time. Load the reference file for each, follow its steps, then verify before moving on:
| Feature | Reference | Load when... |
|---|---|---|
| Error Monitoring | ${SKILL_ROOT}/references/error-monitoring.md |
Always (baseline) |
| Tracing & Performance | ${SKILL_ROOT}/references/tracing.md |
Always — navigation, HTTP, DB spans |
| Session Replay | ${SKILL_ROOT}/references/session-replay.md |
iOS/Android user-facing apps |
| Profiling | ${SKILL_ROOT}/references/profiling.md |
iOS/macOS performance-sensitive apps |
| Logging | ${SKILL_ROOT}/references/logging.md |
Structured logging / log-trace correlation |
| Metrics | ${SKILL_ROOT}/references/metrics.md |
Custom business metrics (open beta) |
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
Configuration Reference
Core SentryFlutter.init() Options
| Option | Type | Default | Purpose |
|---|---|---|---|
dsn |
string |
— | Required. Project DSN. Env: SENTRY_DSN via --dart-define |
environment |
string |
— | e.g., "production", "staging". Env: SENTRY_ENVIRONMENT |
release |
string |
Auto on iOS/Android | "packageName@version+build". Env: SENTRY_RELEASE |
dist |
string |
— | Distribution identifier; max 64 chars. Env: SENTRY_DIST |
sendDefaultPii |
bool |
false |
Include PII: IP address, user labels, widget text in replay |
sampleRate |
double |
1.0 |
Error event sampling (0.0–1.0) |
maxBreadcrumbs |
int |
100 |
Max breadcrumbs per event |
attachStacktrace |
bool |
true |
Auto-attach stack traces to messages |
attachScreenshot |
bool |
false |
Capture screenshot on error (mobile/desktop only) |
screenshotQuality |
enum | high |
Screenshot quality: full, high, medium, low |
attachViewHierarchy |
bool |
false |
Attach JSON widget tree as attachment on error |
debug |
bool |
true in debug |
Verbose SDK output. Never force true in production |
diagnosticLevel |
enum | warning |
Log verbosity: debug, info, warning, error, fatal |
enabled |
bool |
true |
Disable SDK entirely (e.g., for testing) |
maxCacheItems |
int |
30 |
Max offline-cached envelopes (not supported on Web) |
sendClientReports |
bool |
true |
Send SDK health reports (dropped events, etc.) |
reportPackages |
bool |
true |
Report pubspec.yaml dependency list |
reportSilentFlutterErrors |
bool |
false |
Capture FlutterErrorDetails.silent errors |
idleTimeout |
Duration |
3000ms |
Auto-finish idle user interaction transactions |
Tracing Options
| Option | Type | Default | Purpose |
|---|---|---|---|
tracesSampleRate |
double |
— | Transaction sample rate (0–1). Enable by setting >0 |
tracesSampler |
function |
— | Per-transaction sampling; overrides tracesSampleRate |
tracePropagationTargets |
List |
— | URLs to attach sentry-trace + baggage headers |
propagateTraceparent |
bool |
false |
Also send W3C traceparent header (SDK ≥9.7.0) |
enableTimeToFullDisplayTracing |
bool |
false |
Opt-in TTFD tracking per screen |
enableAutoPerformanceTracing |
bool |
true |
Auto-enable performance monitoring |
enableUserInteractionTracing |
bool |
true |
Create transactions for tap/click/long-press events |
enableUserInteractionBreadcrumbs |
bool |
true |
Breadcrumbs for every tracked user interaction |
Profiling Options
| Option | Type | Default | Purpose |
|---|---|---|---|
profilesSampleRate |
double |
— | Profiling rate relative to tracesSampleRate. iOS/macOS only |
Native / Mobile Options
| Option | Type | Default | Purpose |
|---|---|---|---|
autoInitializeNativeSdk |
bool |
true |
Auto-initialize native Android/iOS SDK layer |
enableNativeCrashHandling |
bool |
true |
Capture native crashes (NDK, signal, Mach exception) |
enableNdkScopeSync |
bool |
true |
Sync Dart scope to Android NDK |
enableScopeSync |
bool |
true |
Sync scope data to native SDKs |
anrEnabled |
bool |
true |
ANR detection (Android) |
anrTimeoutInterval |
int |
5000 |
ANR timeout in milliseconds (Android) |
enableWatchdogTerminationTracking |
bool |
true |
OOM kill tracking (iOS) |
enableTombstone |
bool |
false |
Android 12+ native crash info via ApplicationExitInfo |
attachThreads |
bool |
false |
Attach all threads on crash (Android) |
captureNativeFailedRequests |
bool |
— | Native HTTP error capture, independent of Dart client (iOS/macOS, v9.11.0+) |
enableAutoNativeAppStart |
bool |
true |
App start timing instrumentation (iOS/Android) |
enableFramesTracking |
bool |
true |
Slow/frozen frame monitoring (iOS/Android/macOS) |
proguardUuid |
string |
— | Proguard UUID for Android obfuscation mapping |
Session & Release Health Options
| Option | Type | Default | Purpose |
|---|---|---|---|
enableAutoSessionTracking |
bool |
true |
Session tracking for crash-free user/session metrics |
autoSessionTrackingInterval |
Duration |
30s |
Background inactivity before session ends |
Replay Options (options.replay)
| Option | Type | Default | Purpose |
|---|---|---|---|
replay.sessionSampleRate |
double |
0.0 |
Fraction of all sessions recorded |
replay.onErrorSampleRate |
double |
0.0 |
Fraction of error sessions recorded |
Replay Privacy Options (options.privacy)
| Option / Method | Default | Purpose |
|---|---|---|
privacy.maskAllText |
true |
Mask all text widget content |
privacy.maskAllImages |
true |
Mask all image widgets |
privacy.maskAssetImages |
true |
Mask images from root asset bundle |
privacy.mask<T>() |
— | Mask a specific widget type and all subclasses |
privacy.unmask<T>() |
— | Unmask a specific widget type |
privacy.maskCallback<T>() |
— | Custom masking decision per widget instance |
HTTP Options
| Option | Type | Default | Purpose |
|---|---|---|---|
captureFailedRequests |
bool |
true (Flutter) |
Auto-capture HTTP errors |
maxRequestBodySize |
enum | never |
Body capture: never, small, medium, always |
failedRequestStatusCodes |
List |
[500–599] |
Status codes treated as failures |
failedRequestTargets |
List |
['.*'] |
URL patterns to monitor |
Hook Options
| Option | Type | Purpose |
|---|---|---|
beforeSend |
(SentryEvent, Hint) → SentryEvent? |
Modify or drop error events. Return null to drop |
beforeSendTransaction |
(SentryEvent) → SentryEvent? |
Modify or drop transaction events |
beforeBreadcrumb |
(Breadcrumb, Hint) → Breadcrumb? |
Process breadcrumbs before storage |
beforeSendLog |
(SentryLog) → SentryLog? |
Filter structured logs before sending |
Environment Variables
Pass via --dart-define at build time:
| Variable | Purpose | Notes |
|---|---|---|
SENTRY_DSN |
Data Source Name | Falls back from options.dsn |
SENTRY_ENVIRONMENT |
Deployment environment | Falls back from options.environment |
SENTRY_RELEASE |
Release identifier | Falls back from options.release |
SENTRY_DIST |
Build distribution | Falls back from options.dist |
SENTRY_AUTH_TOKEN |
Upload debug symbols | Never embed in app — build tool only |
SENTRY_ORG |
Organization slug | Used by sentry_dart_plugin |
SENTRY_PROJECT |
Project slug | Used by sentry_dart_plugin |
Usage:
flutter build apk --release \
--dart-define=SENTRY_DSN=https://xxx@sentry.io/123 \
--dart-define=SENTRY_ENVIRONMENT=production
Then in code:
options.dsn = const String.fromEnvironment('SENTRY_DSN');
options.environment = const String.fromEnvironment('SENTRY_ENVIRONMENT', defaultValue: 'development');
Ecosystem Integrations
Add these packages alongside sentry_flutter for deeper instrumentation:
HTTP Clients
Standard http package — built into sentry_flutter, no extra install:
import 'package:sentry/sentry.dart';
// Wrap your http client
final client = SentryHttpClient(
captureFailedRequests: true,
failedRequestStatusCodes: [SentryStatusCode.range(400, 599)],
);
try {
final response = await client.get(Uri.parse('https://api.example.com/users'));
} finally {
client.close();
}
Dio — install sentry_dio:
flutter pub add sentry_dio
import 'package:dio/dio.dart';
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
// Add your interceptors first, THEN addSentry() last
dio.addSentry(
captureFailedRequests: true,
failedRequestStatusCodes: [SentryStatusCode.range(400, 599)],
);
Databases
| Package | Install | Setup |
|---|---|---|
sentry_sqflite |
flutter pub add sentry_sqflite |
databaseFactory = SentrySqfliteDatabaseFactory(); |
sentry_drift |
flutter pub add sentry_drift |
.interceptWith(SentryQueryInterceptor(databaseName: 'db')) |
sentry_hive |
flutter pub add sentry_hive |
Use SentryHive instead of Hive |
sentry_isar |
flutter pub add sentry_isar |
Use SentryIsar.open() instead of Isar.open() |
Other
| Package | Install | Purpose |
|---|---|---|
sentry_logging |
flutter pub add sentry_logging |
Dart logging package → Sentry breadcrumbs/events |
sentry_link |
flutter pub add sentry_link |
GraphQL (gql, graphql_flutter, ferry) tracing |
sentry_supabase |
flutter pub add sentry_supabase |
Supabase query tracing (SDK ≥9.9.0) |
sentry_firebase_remote_config |
flutter pub add sentry_firebase_remote_config |
Feature flag tracking |
sentry_file |
flutter pub add sentry_file |
File I/O tracing via .sentryTrace() extension |
State Management Patterns
No official packages — wire Sentry via observer APIs:
| Framework | Hook point | Pattern |
|---|---|---|
| BLoC/Cubit | BlocObserver.onError |
Sentry.captureException(error, stackTrace: stackTrace) inside onError; set Bloc.observer = SentryBlocObserver() before init |
| Riverpod | ProviderObserver.providerDidFail |
Fires for FutureProvider/StreamProvider failures; wrap app with ProviderScope(observers: [SentryProviderObserver()]) |
| Provider/ChangeNotifier | try/catch in notifyListeners callers |
Manually call Sentry.captureException(e, stackTrace: stack) in catch blocks |
| GetX | GetMaterialApp.onError |
GetMaterialApp(onError: (details) => Sentry.captureException(...)) |
Production Settings
Lower sample rates and harden config before shipping:
Future<void> main() async {
final isProduction = const bool.fromEnvironment('dart.vm.product');
await SentryFlutter.init(
(options) {
options.dsn = const String.fromEnvironment('SENTRY_DSN');
options.environment = isProduction ? 'production' : 'development';
// Trace 10% of transactions in high-traffic production
options.tracesSampleRate = isProduction ? 0.1 : 1.0;
// Profile 100% of traced transactions (profiling is always a subset)
options.profilesSampleRate = 1.0;
// Replay all error sessions, sample 5% of normal sessions
options.replay.onErrorSampleRate = 1.0;
options.replay.sessionSampleRate = isProduction ? 0.05 : 1.0;
// Disable debug logging in production
options.debug = !isProduction;
},
appRunner: () => runApp(SentryWidget(child: MyApp())),
);
}
Verification
After setup, test that Sentry is receiving events:
// Add a test button somewhere visible during development:
ElevatedButton(
onPressed: () {
throw Exception('Sentry test error!');
},
child: const Text('Test Sentry Error'),
)
// Or capture manually:
ElevatedButton(
onPressed: () {
Sentry.captureMessage('Sentry test message', level: SentryLevel.info);
},
child: const Text('Test Sentry Message'),
)
// Test structured logging:
ElevatedButton(
onPressed: () {
Sentry.logger.info('Test log from Flutter app');
},
child: const Text('Test Sentry Log'),
)
Check the Sentry dashboard:
- Issues → test error should appear within seconds
- Traces → look for a navigation transaction with child spans
- Replays → session recording visible after app interaction (iOS/Android only)
- Logs → structured log entries if
enableLogs: true
⚠️ Platform limitations in debug mode:
- Native crashes, session replay, slow/frozen frames, and app start metrics only fully work in release builds on iOS/Android
- Run
flutter run --releaseor use a real device/emulator to test native features- Debug mode uses the Dart VM with JIT compilation — some native integrations behave differently
Default Auto-Enabled Integrations
These are active with no extra config when you call SentryFlutter.init():
| Integration | What it does |
|---|---|
FlutterErrorIntegration |
Captures FlutterError.onError framework errors |
RunZonedGuardedIntegration |
Catches unhandled Dart exceptions in runZonedGuarded |
NativeAppStartIntegration |
App start timing (iOS/Android) |
FramesTrackingIntegration |
Slow/frozen frames (iOS/Android/macOS) |
NativeUserInteractionIntegration |
User interaction breadcrumbs from native layer |
UserInteractionIntegration |
Dart-layer tap/click transactions (requires SentryWidget) |
DeviceContextIntegration |
Device model, OS version, screen resolution |
AppContextIntegration |
App version, build number, bundle ID |
ConnectivityIntegration |
Network connectivity change breadcrumbs |
HttpClientIntegration |
Auto-instrument Dart http requests |
SdkIntegration |
SDK metadata tagging |
ReleaseIntegration |
Auto-set release on iOS/Android from package info |
Phase 4: Cross-Link
After completing Flutter setup, check for a backend missing Sentry coverage:
# Adjacent backend directories
ls ../backend ../server ../api 2>/dev/null
cat ../go.mod 2>/dev/null | head -3
cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3
cat ../Gemfile 2>/dev/null | head -3
ls ../backend/package.json ../server/package.json 2>/dev/null
If a backend exists without Sentry, suggest the matching skill:
| Detected | Suggest skill |
|---|---|
Go backend (go.mod) |
sentry-go-sdk |
Python backend (requirements.txt, pyproject.toml) |
sentry-python-sdk |
Ruby backend (Gemfile) |
sentry-ruby-sdk |
| Node.js backend | sentry-node-sdk |
.NET backend (*.csproj) |
sentry-dotnet-sdk |
| React / Next.js web | sentry-react-sdk / sentry-nextjs-sdk |
Distributed tracing — if a backend skill is added, configure tracePropagationTargets in Flutter to propagate trace context to your API:
options.tracePropagationTargets = ['api.myapp.com', 'localhost'];
options.propagateTraceparent = true; // also send W3C traceparent header
This links mobile transactions to backend traces in the Sentry waterfall view.
Troubleshooting
| Issue | Solution |
|---|---|
| Events not appearing in Sentry | Set options.debug = true — SDK logs to Flutter console; verify DSN is correct |
SentryFlutter.init throws |
Ensure main() is async and you await SentryFlutter.init(...) |
| Stack traces unreadable in Sentry | Upload debug symbols with sentry_dart_plugin; build with --obfuscate --split-debug-info |
| Stack traces missing on Web | Build with --source-maps and run dart run sentry_dart_plugin to upload |
| Native crashes not captured | Confirm enableNativeCrashHandling: true; test in release mode, not debug |
| Session replay not recording | iOS/Android only; confirm SentryWidget wraps root; check replay.onErrorSampleRate |
| Replay shows blank screens | Confirm SentryWidget(child: MyApp()) is outermost widget; not inside navigator |
| Profiling not working | iOS and macOS only (alpha); confirm tracesSampleRate > 0 is set first |
| Navigation not tracked | Add SentryNavigatorObserver() to navigatorObservers; name all routes |
| GoRouter routes unnamed | Add name: to all GoRoute entries — unnamed routes are tracked as null |
| TTFD never reports | Call SentryFlutter.currentDisplay()?.reportFullyDisplayed() after data loads, or wrap with SentryDisplayWidget |
sentry_dart_plugin auth error |
Set SENTRY_AUTH_TOKEN env var instead of hardcoding in pubspec.yaml |
| Android ProGuard mapping missing | Ensure --extra-gen-snapshot-options=--save-obfuscation-map=... flag is set |
| iOS dSYM not uploaded | sentry_dart_plugin handles this; check upload_debug_symbols: true in pubspec.yaml sentry: block |
pub get fails: Dart SDK too old |
sentry_flutter ≥9.0.0 requires Dart ≥3.5.0; run flutter upgrade |
| Hot restart crashes on Android debug | Known issue (fixed in SDK ≥9.9.0); upgrade if on older version |
| ANR detection too aggressive | Increase anrTimeoutInterval (default: 5000ms) |
| Too many transactions in dashboard | Lower tracesSampleRate to 0.1 or use tracesSampler to drop health checks |
beforeSend not firing for native crashes |
Expected — beforeSend intercepts only Dart-layer events; native crashes bypass it |
| Crons not available | The Flutter/Dart SDK does not support Sentry Crons; use a server-side SDK instead |
| Metrics marked as experimental | sentry_flutter Metrics API is open beta (SDK ≥9.11.0); stable on other SDKs |
SentryWidget warning in tests |
Wrap test widget with SentryFlutter.init() in setUpAll, or use enabled: false |
| Firebase Remote Config: Linux/Windows | sentry_firebase_remote_config not supported on Linux/Windows (Firebase limitation) |
| Isar tracing on Web | sentry_isar does NOT support Web (Isar does not support Web) |