From a9b474b36cd222be101721beac7807d421f5566d Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Fri, 31 Jul 2026 10:56:44 +0200 Subject: [PATCH 1/8] docs(flutter): Add standalone app start tracing docs App start data is attached to the first ui.load transaction by default, which mixes startup timing with screen-display timing. Document the experimental enableStandaloneAppStartTracing option that reports the app start as its own app.start transaction, along with extendAppStart and finishExtendedAppStart for covering startup work that runs past the first frame. Shipped in sentry-dart 9.26.0. Refs getsentry/sentry-dart#3896 Refs getsentry/sentry-dart#3918 Co-authored-by: Cursor --- .../guides/flutter/configuration/options.mdx | 6 ++ .../dart/guides/flutter/tracing/index.mdx | 19 +++++ .../app-start-instrumentation.mdx | 79 ++++++++++++++++++- 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/docs/platforms/dart/guides/flutter/configuration/options.mdx b/docs/platforms/dart/guides/flutter/configuration/options.mdx index 4143a5a2f7ecde..49a19d02021fc5 100644 --- a/docs/platforms/dart/guides/flutter/configuration/options.mdx +++ b/docs/platforms/dart/guides/flutter/configuration/options.mdx @@ -276,6 +276,12 @@ Controls whether the SDK should propagate the W3C `traceparent` HTTP header alon + + +Set this boolean to `true` to report the app start as its own `app.start` transaction instead of attaching it to the first `ui.load` transaction. Requires tracing to be enabled and is only supported on Android and iOS. This option is experimental. Learn more in our App Start Instrumentation docs. + + + ## Experimental Features diff --git a/docs/platforms/dart/guides/flutter/tracing/index.mdx b/docs/platforms/dart/guides/flutter/tracing/index.mdx index 0cef16789be3ae..b99f70a265edad 100644 --- a/docs/platforms/dart/guides/flutter/tracing/index.mdx +++ b/docs/platforms/dart/guides/flutter/tracing/index.mdx @@ -35,6 +35,25 @@ Test out tracing by starting and finishing a transaction, which you _must_ do so While you're testing, set to `1.0`, as that ensures that every transaction will be sent to Sentry. Once testing is complete, you may want to set a lower value, or switch to using to selectively sample and filter your transactions, based on contextual data. +## Standalone App Start Tracing + + + +This feature is experimental and available since [version 9.26.0](https://github.com/getsentry/sentry-dart/blob/main/CHANGELOG.md#9260). The API is subject to change and may introduce breaking changes in future releases. + + + +By default, app start data is attached to the first `ui.load` transaction in your app. Standalone app start tracing sends the app start as its own transaction instead, which gives you more accurate app start measurements because they no longer depend on a screen transaction being started. It's supported on Android and iOS. + +```dart +await SentryFlutter.init((options) { + options.tracesSampleRate = 1.0; + options.enableStandaloneAppStartTracing = true; +}); +``` + +For more details, including how to extend the app start past the first frame, see App Start Instrumentation. + ## Next Steps diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 2212c45a5872e6..60fbaef4ae1f38 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -25,10 +25,13 @@ Before diving into the configuration, it's important to understand how app start App start instrumentation tracks the duration between the earliest native process initialization and the first frame rendered (as reported by [addTimingsCallback](https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addTimingsCallback.html)). Once the app start is processed, the callback is removed to avoid additional overhead. When the SDK receives the start and end times of the app launch, the SDK: + - Creates a transaction named `ui.load` - Attaches a span with either `app.start.cold` or `app.start.warm` operation - Adds app start metrics to the transaction +If you'd rather have the app start reported as its own transaction, see [Standalone App Start Tracing](#standalone-app-start-tracing). + Sentry's App Start instrumentation aims to be as comprehensive and representative of the user experience as possible, and adheres to guidelines by the platform vendors. For this reason, App Starts reported by Sentry might be longer than what you see in other tools. @@ -66,6 +69,80 @@ Open the [sentry.io performance page](https://sentry.io/performance), find, and Select the event within your transaction. Sentry displays the app start metrics on the right side of the screen in the **Mobile Vitals** section. +## Standalone App Start Tracing + + + +This feature is experimental and available since [version 9.26.0](https://github.com/getsentry/sentry-dart/blob/main/CHANGELOG.md#9260). The API is subject to change and may introduce breaking changes in future releases. + + + +By default, app start data is attached to the first `ui.load` transaction in your app, which mixes startup timing with screen-display timing. Standalone app start tracing sends the app start as its own `App Start` transaction with the `app.start` operation instead. This gives you more accurate measurements, because they no longer depend on a screen transaction being started, and it lets you sample app starts independently. + +To enable it: + +```dart +await SentryFlutter.init((options) { + options.tracesSampleRate = 1.0; + options.enableStandaloneAppStartTracing = true; +}); +``` + +Standalone app start tracing requires tracing to be enabled and is only supported on Android and iOS. On every other platform the SDK keeps attaching app start data to the first `ui.load` transaction. + +Because the transaction uses the `app.start` operation, you can use `tracesSampler` to give app starts a dedicated sample rate without raising your overall sample rate: + +```dart +await SentryFlutter.init((options) { + options.enableStandaloneAppStartTracing = true; + options.tracesSampler = (samplingContext) { + if (samplingContext.transactionContext.operation == 'app.start') { + return 1.0; + } + return 0.1; + }; +}); +``` + +### Extending the App Start + +The app start ends when the first frame renders. If your app does startup work that runs past that point — loading initial data from a server or a database, for example — call `SentryFlutter.extendAppStart()` to include that work in the reported duration, then `SentryFlutter.finishExtendedAppStart()` once it's done. + +Call `extendAppStart()` before the first frame renders. The `appRunner` callback of `SentryFlutter.init`, before `runApp`, is the safest place. Pair the two calls in a `try`/`finally` so an early return or a thrown exception can't leave the app start open. + +```dart +await SentryFlutter.init( + (options) { + options.tracesSampleRate = 1.0; + options.enableStandaloneAppStartTracing = true; + }, + appRunner: () async { + SentryFlutter.extendAppStart(); + runApp(const MyApp()); + + try { + await loadStartupConfiguration(); + } finally { + await SentryFlutter.finishExtendedAppStart(); + } + }, +); +``` + +This adds an `Extended App Start` span with the `app.start.extended` operation, covering the time between the two calls. To break that period down further, retrieve the span with `SentryFlutter.getExtendedAppStartSpan()` and start child spans on it. Spans you start under the extension keep the app start open until they finish, so finish them too if they shouldn't delay it. + + + +Always finish what you extend. While an extension is open the app start is still in progress, and if it hits its 30-second deadline first, the extension is dropped and the reported duration falls back to the first frame. + + + + + +Extending requires standalone app start tracing to be enabled. `extendAppStart()` does nothing when standalone app start tracing is off, when the first frame has already rendered, or when the app start is already extended. Each of those cases is logged rather than reported back to the caller. + + + ## Disable App Start Instrumentation To disable the app start instrumentation, you can remove the `NativeAppStartIntegration` from the `integrations` list in your `SentryFlutter.init` call. @@ -79,4 +156,4 @@ await SentryFlutter.init((options) { (integration) => integration is NativeAppStartIntegration); options.removeIntegration(integration); }); -``` \ No newline at end of file +``` From 1855ca39c98eaffcfe6e58e96cccd4655943031e Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 11:02:51 +0200 Subject: [PATCH 2/8] docs(flutter): Document initState as a call site for extendAppStart The only requirement for extendAppStart is that it runs before the first frame renders, so the root widget's initState works as well as appRunner. Show both as tabs and note that the call has to come before the first await, since awaiting first lets the frame render and the extension is refused. Co-authored-by: Cursor --- .../app-start-instrumentation.mdx | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 60fbaef4ae1f38..45647d208c36e2 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -108,9 +108,9 @@ await SentryFlutter.init((options) { The app start ends when the first frame renders. If your app does startup work that runs past that point — loading initial data from a server or a database, for example — call `SentryFlutter.extendAppStart()` to include that work in the reported duration, then `SentryFlutter.finishExtendedAppStart()` once it's done. -Call `extendAppStart()` before the first frame renders. The `appRunner` callback of `SentryFlutter.init`, before `runApp`, is the safest place. Pair the two calls in a `try`/`finally` so an early return or a thrown exception can't leave the app start open. +The only requirement is that `extendAppStart()` runs before the first frame renders, so both the `appRunner` callback of `SentryFlutter.init` and your root widget's `initState` work. Reach for `initState` when the startup work belongs to your widget tree, and `appRunner` when it doesn't. Either way, pair the two calls in a `try`/`finally` so an early return or a thrown exception can't leave the app start open. -```dart +```dart {tabTitle:appRunner} {mdExpandTabs} await SentryFlutter.init( (options) { options.tracesSampleRate = 1.0; @@ -129,6 +129,31 @@ await SentryFlutter.init( ); ``` +```dart {tabTitle:initState} +class _MyAppState extends State { + @override + void initState() { + super.initState(); + _loadStartupConfiguration(); + } + + Future _loadStartupConfiguration() async { + // Extend first, before any await, so the call can't slip past the first frame. + SentryFlutter.extendAppStart(); + + try { + await loadStartupConfiguration(); + } finally { + await SentryFlutter.finishExtendedAppStart(); + } + } + + // ... +} +``` + +`initState` runs during the first build, which happens before the first frame is rasterized. Call `extendAppStart()` before the first `await` in that method, though — awaiting first gives the frame a chance to render, and the extension is then refused. + This adds an `Extended App Start` span with the `app.start.extended` operation, covering the time between the two calls. To break that period down further, retrieve the span with `SentryFlutter.getExtendedAppStartSpan()` and start child spans on it. Spans you start under the extension keep the app start open until they finish, so finish them too if they shouldn't delay it. From 4d51620ace4d2495c19451e9282840d2a5c5ba34 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 13:31:57 +0200 Subject: [PATCH 3/8] docs(flutter): Add stream mode tab to app start tracesSampler example The sampler reads the operation differently per trace lifecycle: transaction mode exposes it on the transaction context, while stream mode carries it as the span's sentry.op attribute. Accessing transactionContext in stream mode logs an error, so show both variants as tabs. Co-authored-by: Cursor --- .../app-start-instrumentation.mdx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 45647d208c36e2..90615fe2da1120 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -90,9 +90,9 @@ await SentryFlutter.init((options) { Standalone app start tracing requires tracing to be enabled and is only supported on Android and iOS. On every other platform the SDK keeps attaching app start data to the first `ui.load` transaction. -Because the transaction uses the `app.start` operation, you can use `tracesSampler` to give app starts a dedicated sample rate without raising your overall sample rate: +Because the app start uses the `app.start` operation, you can use `tracesSampler` to give app starts a dedicated sample rate without raising your overall sample rate. Where you read that operation depends on your trace lifecycle: transaction mode exposes it on the transaction context, while stream mode carries it as the span's `sentry.op` attribute. -```dart +```dart {tabTitle: Transaction Mode (Default)} {mdExpandTabs} await SentryFlutter.init((options) { options.enableStandaloneAppStartTracing = true; options.tracesSampler = (samplingContext) { @@ -104,6 +104,19 @@ await SentryFlutter.init((options) { }); ``` +```dart {tabTitle: Stream Mode} +await SentryFlutter.init((options) { + options.enableStandaloneAppStartTracing = true; + options.tracesSampler = (samplingContext) { + final operation = samplingContext.spanContext.attributes['sentry.op']?.value; + if (operation == 'app.start') { + return 1.0; + } + return 0.1; + }; +}); +``` + ### Extending the App Start The app start ends when the first frame renders. If your app does startup work that runs past that point — loading initial data from a server or a database, for example — call `SentryFlutter.extendAppStart()` to include that work in the reported duration, then `SentryFlutter.finishExtendedAppStart()` once it's done. From 94c32eadb397ac2855f49c502c9426c58a381780 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 13:36:20 +0200 Subject: [PATCH 4/8] docs(flutter): Add child span example for the extended app start Show how to break the extension down with getExtendedAppStartSpan and getExtendedAppStartSpanV2, one tab per trace lifecycle. Note that the extension span is not the active span, so children need an explicit parentSpan, and that passing a null parentSpan in stream mode starts a root span rather than a child. Co-authored-by: Cursor --- .../app-start-instrumentation.mdx | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 90615fe2da1120..8c2e61742e65f6 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -167,7 +167,50 @@ class _MyAppState extends State { `initState` runs during the first build, which happens before the first frame is rasterized. Call `extendAppStart()` before the first `await` in that method, though — awaiting first gives the frame a chance to render, and the extension is then refused. -This adds an `Extended App Start` span with the `app.start.extended` operation, covering the time between the two calls. To break that period down further, retrieve the span with `SentryFlutter.getExtendedAppStartSpan()` and start child spans on it. Spans you start under the extension keep the app start open until they finish, so finish them too if they shouldn't delay it. +This adds an `Extended App Start` span with the `app.start.extended` operation, covering the time between the two calls. + +#### Breaking Down the Extension + +To see which part of your startup work took the time, retrieve the extension span and attach children to it. Use the getter that matches your trace lifecycle: `getExtendedAppStartSpan()` in transaction mode, `getExtendedAppStartSpanV2()` in stream mode. The other one returns `null`. + +```dart {tabTitle: Transaction Mode (Default)} {mdExpandTabs} +SentryFlutter.extendAppStart(); + +final appStart = SentryFlutter.getExtendedAppStartSpan(); +final child = appStart?.startChild( + 'http.client', + description: 'Fetch remote config', +); + +try { + await fetchRemoteConfig(); +} finally { + await child?.finish(); + await SentryFlutter.finishExtendedAppStart(); +} +``` + +```dart {tabTitle: Stream Mode} +SentryFlutter.extendAppStart(); + +final appStart = SentryFlutter.getExtendedAppStartSpanV2(); + +try { + await Sentry.startSpan( + 'Fetch remote config', + (span) => fetchRemoteConfig(), + parentSpan: appStart, + ); +} finally { + await SentryFlutter.finishExtendedAppStart(); +} +``` + +In stream mode, `startSpan` ends the child for you once the callback completes, so it only needs the parent. The extension span isn't the active span, which is why you have to pass it as `parentSpan` rather than relying on automatic nesting. + +Both getters return `null` when the app start isn't extended. In transaction mode the null-aware calls take care of that. In stream mode, passing `parentSpan: null` means "start a root span", so guard the call if a stray root would be a problem. + +Spans you start under the extension keep the app start open until they finish, so finish them too if they shouldn't delay it. From 283a5966adab38716ef3b7e12eed1ae64fbc376c Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 13:53:02 +0200 Subject: [PATCH 5/8] docs(flutter): Fix disable app start snippet The import pointed at src/integrations/native_app_start_integration.dart, which the SDK moved to src/app_start/ui_load_attached/. Removing that integration alone also no longer disables app start, since standalone tracing runs through StandaloneAppStartIntegration, so remove both. Replace the firstWhere lookup with a loop as well. App start integrations are only registered on the platforms that support them, and firstWhere throws when they are absent. Co-authored-by: Cursor --- .../app-start-instrumentation.mdx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 8c2e61742e65f6..f60198bd108b23 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -226,15 +226,21 @@ Extending requires standalone app start tracing to be enabled. `extendAppStart() ## Disable App Start Instrumentation -To disable the app start instrumentation, you can remove the `NativeAppStartIntegration` from the `integrations` list in your `SentryFlutter.init` call. +App start ships as two integrations: `NativeAppStartIntegration` for the default `ui.load`-attached path, and `StandaloneAppStartIntegration` for standalone app start tracing. The SDK registers both and each one stands down at runtime depending on your configuration, so remove both to turn app start off no matter how it's configured. ```dart -// ignore: implementation_imports -import 'package:sentry_flutter/src/integrations/native_app_start_integration.dart'; +// ignore_for_file: implementation_imports +import 'package:sentry_flutter/src/app_start/standalone/standalone_app_start_integration.dart'; +import 'package:sentry_flutter/src/app_start/ui_load_attached/native_app_start_integration.dart'; await SentryFlutter.init((options) { - final integration = options.integrations.firstWhere( - (integration) => integration is NativeAppStartIntegration); - options.removeIntegration(integration); + for (final integration in options.integrations) { + if (integration is NativeAppStartIntegration || + integration is StandaloneAppStartIntegration) { + options.removeIntegration(integration); + } + } }); ``` + +App start integrations are only registered on the platforms that support them, so don't assume either one is present — looking them up with `firstWhere` throws when they aren't. From d80078da6c957f21ad2d3c9c96a3bbcf3e923bef Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 13:54:32 +0200 Subject: [PATCH 6/8] docs(flutter): Cover the whole extension in try/finally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runApp sat between extendAppStart and the try, so a synchronous throw would leave the extension open until the deadline — the opposite of the guidance right above the snippet. Move it inside the try. Apply the same to the child span examples: startChild was outside the try, and the stream getter now inlines as parentSpan, so nothing that can throw sits between extending and finishing. Co-authored-by: Cursor --- .../app-start-instrumentation.mdx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index f60198bd108b23..36a96c40abea8b 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -131,9 +131,9 @@ await SentryFlutter.init( }, appRunner: () async { SentryFlutter.extendAppStart(); - runApp(const MyApp()); try { + runApp(const MyApp()); await loadStartupConfiguration(); } finally { await SentryFlutter.finishExtendedAppStart(); @@ -176,13 +176,12 @@ To see which part of your startup work took the time, retrieve the extension spa ```dart {tabTitle: Transaction Mode (Default)} {mdExpandTabs} SentryFlutter.extendAppStart(); -final appStart = SentryFlutter.getExtendedAppStartSpan(); -final child = appStart?.startChild( - 'http.client', - description: 'Fetch remote config', -); - +ISentrySpan? child; try { + child = SentryFlutter.getExtendedAppStartSpan()?.startChild( + 'http.client', + description: 'Fetch remote config', + ); await fetchRemoteConfig(); } finally { await child?.finish(); @@ -193,13 +192,11 @@ try { ```dart {tabTitle: Stream Mode} SentryFlutter.extendAppStart(); -final appStart = SentryFlutter.getExtendedAppStartSpanV2(); - try { await Sentry.startSpan( 'Fetch remote config', (span) => fetchRemoteConfig(), - parentSpan: appStart, + parentSpan: SentryFlutter.getExtendedAppStartSpanV2(), ); } finally { await SentryFlutter.finishExtendedAppStart(); From dc513a20ba36016a046f03c4a4d88cfb1a5931c1 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 13:56:33 +0200 Subject: [PATCH 7/8] docs(flutter): Match tab title spacing used by the span streaming docs The in-flight span streaming pages write these as {tabTitle:Stream Mode} without a space after the colon. Drop the space so both land consistently. Co-authored-by: Cursor --- includes/dart-integrations/app-start-instrumentation.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 4ef9005f53cb23..5714e8c7d00c2c 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -94,7 +94,7 @@ Standalone app start tracing requires tracing to be enabled and is only supporte Because the app start uses the `app.start` operation, you can use `tracesSampler` to give app starts a dedicated sample rate without raising your overall sample rate. Where you read that operation depends on your trace lifecycle: transaction mode exposes it on the transaction context, while stream mode carries it as the span's `sentry.op` attribute. -```dart {tabTitle: Transaction Mode (Default)} {mdExpandTabs} +```dart {tabTitle:Transaction Mode (Default)} {mdExpandTabs} await SentryFlutter.init((options) { options.enableStandaloneAppStartTracing = true; options.tracesSampler = (samplingContext) { @@ -106,7 +106,7 @@ await SentryFlutter.init((options) { }); ``` -```dart {tabTitle: Stream Mode} +```dart {tabTitle:Stream Mode} await SentryFlutter.init((options) { options.enableStandaloneAppStartTracing = true; options.tracesSampler = (samplingContext) { @@ -175,7 +175,7 @@ This adds an `Extended App Start` span with the `app.start.extended` operation, To see which part of your startup work took the time, retrieve the extension span and attach children to it. Use the getter that matches your trace lifecycle: `getExtendedAppStartSpan()` in transaction mode, `getExtendedAppStartSpanV2()` in stream mode. The other one returns `null`. -```dart {tabTitle: Transaction Mode (Default)} {mdExpandTabs} +```dart {tabTitle:Transaction Mode (Default)} {mdExpandTabs} SentryFlutter.extendAppStart(); ISentrySpan? child; @@ -191,7 +191,7 @@ try { } ``` -```dart {tabTitle: Stream Mode} +```dart {tabTitle:Stream Mode} SentryFlutter.extendAppStart(); try { From 22aac3699e195625459bb4cfd5991f382d41dd38 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 3 Aug 2026 13:59:07 +0200 Subject: [PATCH 8/8] docs(flutter): Link stream mode to the Streamed Spans page The span streaming docs landed on master in #18764, so the page these snippets refer to now exists. Link it on first mention, matching how the rest of the Dart docs reference stream mode. Co-authored-by: Cursor --- includes/dart-integrations/app-start-instrumentation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/dart-integrations/app-start-instrumentation.mdx b/includes/dart-integrations/app-start-instrumentation.mdx index 5714e8c7d00c2c..c95bd89e4e034f 100644 --- a/includes/dart-integrations/app-start-instrumentation.mdx +++ b/includes/dart-integrations/app-start-instrumentation.mdx @@ -92,7 +92,7 @@ await SentryFlutter.init((options) { Standalone app start tracing requires tracing to be enabled and is only supported on Android and iOS. On every other platform the SDK keeps attaching app start data to the first `ui.load` transaction. -Because the app start uses the `app.start` operation, you can use `tracesSampler` to give app starts a dedicated sample rate without raising your overall sample rate. Where you read that operation depends on your trace lifecycle: transaction mode exposes it on the transaction context, while stream mode carries it as the span's `sentry.op` attribute. +Because the app start uses the `app.start` operation, you can use `tracesSampler` to give app starts a dedicated sample rate without raising your overall sample rate. Where you read that operation depends on your trace lifecycle: transaction mode exposes it on the transaction context, while stream mode carries it as the span's `sentry.op` attribute. ```dart {tabTitle:Transaction Mode (Default)} {mdExpandTabs} await SentryFlutter.init((options) {