The `SnackBar` API within the `Scaffold` is now handled by the `ScaffoldMessenger`, one of which is available by default within the context of a `MaterialApp`.
Original behavior
Prior to this change, `SnackBar`s would be shown by calling on the `Scaffold` within the current `BuildContext`. By calling `Scaffold.of(context).showSnackBar`, the current `Scaffold` would animate a `SnackBar` into view. This would only apply to the current `Scaffold`, and would not persist across routes if they were changed in the course of the `SnackBar`s presentation. This would also lead to errors if `showSnackBar` would be called in the course of executing an asynchronous event, and the `BuildContext` became invalidated by the route changing and the `Scaffold` being disposed of.
New behavior
The previous approach called upon the `Scaffold` to show a `SnackBar`.
- Who is affected
- Applications and packages relying on the previous behaviour or signature. Code that uses SnackBar, Scaffold, ScaffoldMessenger and related APIs.
- Practical impact
- Behaviour or API differences that can break builds or change runtime behaviour.
- What action should I take?
- Follow the official migration guide below, update affected call sites, run `dart fix --apply` where a fix is available, then run your tests.
Before and after (from the official guide)
| 1 | − | // The ScaffoldState of the current context was used for managing SnackBars. |
| 2 | − | Scaffold.of(context).showSnackBar(mySnackBar); |
| 3 | − | Scaffold.of(context).hideCurrentSnackBar(mySnackBar); |
| 4 | − | Scaffold.of(context).removeCurrentSnackBar(mySnackBar); |
| 5 | ||
| 6 | − | // If a Scaffold.key is specified, the ScaffoldState can be directly |
| 7 | // accessed without first obtaining it from a BuildContext via | |
| 8 | − | // Scaffold.of. From the key, use the GlobalKey.currentState |
| 9 | − | // getter. This was previously used to manage SnackBars. |
| 10 | − | final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); |
| 11 | − | Scaffold( |
| 12 | − | key: scaffoldKey, |
| 13 | − | body: ..., |
| 14 | − | ); |
| 15 | ||
| 16 | − | scaffoldKey.currentState.showSnackBar(mySnackBar); |
| 17 | − | scaffoldKey.currentState.hideCurrentSnackBar(mySnackBar); |
| 18 | − | scaffoldKey.currentState.removeCurrentSnackBar(mySnackBar); |
| 1 | + | // The ScaffoldMessengerState of the current context is used for managing SnackBars. |
| 2 | + | ScaffoldMessenger.of(context).showSnackBar(mySnackBar); |
| 3 | + | ScaffoldMessenger.of(context).hideCurrentSnackBar(mySnackBar); |
| 4 | + | ScaffoldMessenger.of(context).removeCurrentSnackBar(mySnackBar); |
| 5 | ||
| 6 | + | // If a ScaffoldMessenger.key is specified, the ScaffoldMessengerState can be directly |
| 7 | // accessed without first obtaining it from a BuildContext via | |
| 8 | + | // ScaffoldMessenger.of. From the key, use the GlobalKey.currentState |
| 9 | + | // getter. This is used to manage SnackBars. |
| 10 | + | final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>(); |
| 11 | + | ScaffoldMessenger( |
| 12 | + | key: scaffoldMessengerKey, |
| 13 | + | child: ... |
| 14 | + | ) |
| 15 | ||
| 16 | + | scaffoldMessengerKey.currentState.showSnackBar(mySnackBar); |
| 17 | + | scaffoldMessengerKey.currentState.hideCurrentSnackBar(mySnackBar); |
| 18 | + | scaffoldMessengerKey.currentState.removeCurrentSnackBar(mySnackBar); |
| 19 | + | |
| 20 | + | // The root ScaffoldMessenger can also be accessed by providing a key to |
| 21 | + | // MaterialApp.scaffoldMessengerKey. This way, the ScaffoldMessengerState can be directly accessed |
| 22 | + | // without first obtaining it from a BuildContext via ScaffoldMessenger.of. From the key, use |
| 23 | + | // the GlobalKey.currentState getter. |
| 24 | + | final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>(); |
| 25 | + | MaterialApp( |
| 26 | + | scaffoldMessengerKey: rootScaffoldMessengerKey, |
| 27 | + | home: ... |
| 28 | + | ) |
| 29 | + | |
| 30 | + | rootScaffoldMessengerKey.currentState.showSnackBar(mySnackBar); |
| 31 | + | rootScaffoldMessengerKey.currentState.hideCurrentSnackBar(mySnackBar); |
| 32 | + | rootScaffoldMessengerKey.currentState.removeCurrentSnackBar(mySnackBar); |
Raw before / after
// The ScaffoldState of the current context was used for managing SnackBars. Scaffold.of(context).showSnackBar(mySnackBar); Scaffold.of(context).hideCurrentSnackBar(mySnackBar); Scaffold.of(context).removeCurrentSnackBar(mySnackBar); // If a Scaffold.key is specified, the ScaffoldState can be directly // accessed without first obtaining it from a BuildContext via // Scaffold.of. From the key, use the GlobalKey.currentState // getter. This was previously used to manage SnackBars. final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); Scaffold( key: scaffoldKey, body: ..., ); scaffoldKey.currentState.showSnackBar(mySnackBar); scaffoldKey.currentState.hideCurrentSnackBar(mySnackBar); scaffoldKey.currentState.removeCurrentSnackBar(mySnackBar);
// The ScaffoldMessengerState of the current context is used for managing SnackBars. ScaffoldMessenger.of(context).showSnackBar(mySnackBar); ScaffoldMessenger.of(context).hideCurrentSnackBar(mySnackBar); ScaffoldMessenger.of(context).removeCurrentSnackBar(mySnackBar); // If a ScaffoldMessenger.key is specified, the ScaffoldMessengerState can be directly // accessed without first obtaining it from a BuildContext via // ScaffoldMessenger.of. From the key, use the GlobalKey.currentState // getter. This is used to manage SnackBars. final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>(); ScaffoldMessenger( key: scaffoldMessengerKey, child: ... ) scaffoldMessengerKey.currentState.showSnackBar(mySnackBar); scaffoldMessengerKey.currentState.hideCurrentSnackBar(mySnackBar); scaffoldMessengerKey.currentState.removeCurrentSnackBar(mySnackBar); // The root ScaffoldMessenger can also be accessed by providing a key to // MaterialApp.scaffoldMessengerKey. This way, the ScaffoldMessengerState can be directly accessed // without first obtaining it from a BuildContext via ScaffoldMessenger.of. From the key, use // the GlobalKey.currentState getter. final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>(); MaterialApp( scaffoldMessengerKey: rootScaffoldMessengerKey, home: ... ) rootScaffoldMessengerKey.currentState.showSnackBar(mySnackBar); rootScaffoldMessengerKey.currentState.hideCurrentSnackBar(mySnackBar); rootScaffoldMessengerKey.currentState.removeCurrentSnackBar(mySnackBar);
Official migration guide (excerpt, © The Flutter Authors, CC BY 3.0)
Code before migration:
// The ScaffoldState of the current context was used for managing SnackBars.
Scaffold.of(context).showSnackBar(mySnackBar);
Scaffold.of(context).hideCurrentSnackBar(mySnackBar);
Scaffold.of(context).removeCurrentSnackBar(mySnackBar);
// If a Scaffold.key is specified, the ScaffoldState can be directly
// accessed without first obtaining it from a BuildContext via
// Scaffold.of. From the key, use the GlobalKey.currentState
// getter. This was previously used to manage SnackBars.
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
Scaffold(
key: scaffoldKey,
body: ...,
);
scaffoldKey.currentState.showSnackBar(mySnackBar);
scaffoldKey.currentState.hideCurrentSnackBar(mySnackBar);
scaffoldKey.currentState.removeCurrentSnackBar(mySnackBar);
Code after migration:
// The ScaffoldMessengerState of the current context is used for managing SnackBars.
ScaffoldMessenger.of(context).showSnackBar(mySnackBar);
ScaffoldMessenger.of(context).hideCurrentSnackBar(mySnackBar);
ScaffoldMessenger.of(context).removeCurrentSnackBar(mySnackBar);
// If a ScaffoldMessenger.key is specified, the ScaffoldMessengerState can be directly
// accessed without first obtaining it from a BuildContext via
// ScaffoldMessenger.of. From the key, use the GlobalKey.currentState
// getter. This is used to manage SnackBars.
final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
ScaffoldMessenger(
key: scaffoldMessengerKey,
child: ...
)
scaffoldMessengerKey.currentState.showSnackBar(mySnackBar);
scaffoldMessengerKey.currentState.hideCurrentSnackBar(mySnackBar);
scaffoldMessengerKey.currentState.removeCurrentSnackBar(mySnackBar);
// The root ScaffoldMessenger can also be accessed by providing a key to
// MaterialApp.scaffoldMessengerKey. This way, the ScaffoldMessengerState can be directly accessed
// without first obtaining it from a BuildContext via ScaffoldMessenger.of. From the key, use
// the GlobalKey.currentState getter.
final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
MaterialApp(
scaffoldMessengerKey: rootScaffoldMessengerKey,
home: ...
)
rootScaffoldMessengerKey.currentState.showSnackBar(mySnackBar);
rootScaffoldMessengerKey.currentState.hideCurrentSnackBar(mySnackBar);
rootScaffoldMessengerKey.currentState.removeCurrentSnackBar(mySnackBar);AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.Listed in the official breaking-changes index (docs.flutter.dev/release/breaking-changes).
An official announcement or migration guide documents an intended behaviour or API change. A verified source change (git diff) shows code changed but does not by itself prove a public API is breaking. AI interpretations are labelled and never used to classify a change.
- Source commit
- b3045439b7c0
- Source last updated
- Oct 21, 2026
- Last synchronized
- Oct 21, 2026
- Publication status
- published
Publication history
- Oct 21, 2026, 8:31 PM: new → published (ingestion) — Backed by an official breaking-change/migration guide.
AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.