ScaffoldMessenger Widget in Flutter: Custom SnackBars

- 👤 Andrés Cruz

🇪🇸 En español

When I started working with visual feedback in Flutter, I discovered that ScaffoldMessenger was exactly what I needed to show quick confirmations, almost like the "flash messages" in web apps. That same pattern I use when deleting a record or confirming a payment was solved cleanly and consistently with this tool.

In this guide, I'll tell you what it is, how it works, when to use it, and I'll give you three practical examples of custom SnackBars, including an advanced one with Stack, icons, and a full design.

We left off with the fact that we managed to implement the pinch effect in Flutter, let's move on to another topic.

What is ScaffoldMessenger and why it replaces the old Scaffold.of(context)

If you ever used Scaffold.of(context).showSnackBar(), you surely ran into the infamous invalid context error. It happened to me too at first: I couldn't show a message right after navigating or when executing an asynchronous action.

That's where ScaffoldMessenger comes in: a global widget capable of managing SnackBars without depending on the immediate context.

Difference Between the Two Approaches

  • Scaffold.of(context) → Depends on the widget tree. If the context doesn't have access to the Scaffold, it fails.
  • ScaffoldMessenger.of(context) → Placed at the root (MaterialApp) and manages messages from anywhere.

Real Advantages When Working with SnackBars

  • More stable when working with navigation.
  • Ideal for showing messages after operations like deleting, updating, or paying (it works for exactly those cases for me).
  • Allows for more complex, animated, or custom layout SnackBars.

When to Use ScaffoldMessenger: Real-World Daily Cases

Using ScaffoldMessenger makes sense when you need to confirm important actions or provide immediate feedback without interrupting navigation.

"Flash" Type Messages After Critical Actions

In my projects, I use it when:

  • I delete a record,
  • I process a payment,
  • I confirm a change in a form,
  • I notify the user that something did happen.

That kind of quick communication significantly boosts the user experience.

Confirmations (Payments, Deletions, Edits)

A key thing is that the message appears even if you've just navigated. That's where ScaffoldMessenger is a lifesaver; it never fails due to having a "stale" context.

Practical Examples of ScaffoldMessenger in Flutter

We will explore Flash error messages in Flutter by customizing a ScaffoldMessenger-type message.

We are going to implement the following structure:

Column(
  crossAxisAlignment: CrossAxisAlignment.center,
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Image.asset('assets/logo.png',height: 300,width: 350,),
    Center(
      child: ElevatedButton(
          style: ElevatedButton.styleFrom(
              primary: Colors.cyan,
          ),
          onPressed: () {
            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                content: Text(
                    ¡Este nombre de usuario no se encuentra!)));
          },
          child: const Text('Show Flash Error Message')),
    ),
  ],
),

Inside ElevatedButton, we will add the style and the onPressed function. In this function, we will create a simple SnackBar() method. In this method, we will add content that is equal to the text 'This username is not found! Please try again later.' 

Now, this time everything is the same but only changes in SnackBar(). Inside SnackBar(), we will add a behavior equal to SnackBarBehavior.floating and content equal to the Container widget. In this widget, we will add padding, height, and the BoxDecoration with blue color and circular border radius.

ElevatedButton(
    style: ElevatedButton.styleFrom(
      primary: Colors.cyan,
    ),
    onPressed: () {
      ScaffoldMessenger.of(context).showSnackBar( SnackBar(
        behavior: SnackBarBehavior.floating,
          content: Container(
            padding: const EdgeInsets.all(8),
            height: 70,
            decoration:  const BoxDecoration(
              color: Colors.blue,
              borderRadius: BorderRadius.all(Radius.circular(15)),
            ),
            child: const Center(
              child: Text(
                'This Username is not found! Please try again later'),
            ),
          ),
      ));
    },
    child: const Text('Show Flash Error Message')),

Last but not least, this time we will make other changes in SnackBar() inside ElevatedButton(). Inside, we will add a transparent background color, behavior equal to SnackBarBehavior.floating, elevation is 0, and content equal to the Stack() widget. 

Inside the widget, we will add alignment at the center, clipBehavior to none. We will also add a Row widget. In this widget, we will add a Column. In this Column, we will add two Text widgets.

ElevatedButton(
    style: ElevatedButton.styleFrom(
      primary: Colors.cyan,
    ),
    onPressed: () {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        backgroundColor: Colors.transparent,
        behavior: SnackBarBehavior.floating,
        elevation: 0,
        content: Stack(
          alignment: Alignment.center,
          clipBehavior: Clip.none,
          children: [
            Container(
              padding: const EdgeInsets.all(8),
              height: 70,
              decoration: const BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.all(Radius.circular(15)),
              ),
              child: Row(
                children: [
                  const SizedBox(
                    width: 48,
                  ),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: const [
                        Text(
                          'Oops Error!',
                          style: TextStyle(
                              fontSize: 18, color: Colors.white),
                        ),
                        Text(
                          'This Username is not found! Please try again later',
                          style: TextStyle(
                              fontSize: 14, color: Colors.white),
                          maxLines: 2,
                          overflow: TextOverflow.ellipsis,
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            Positioned(
                bottom: 25,
                left: 20,
                child: ClipRRect(
                  child: Stack(
                    children: [
                      Icon(
                        Icons.circle,
                        color: Colors.red.shade200,
                        size: 17,
                      )
                    ],
                  ),
                )),
            Positioned(
                top: -20,
                left: 5,
                child: Stack(
                  alignment: Alignment.center,
                  children: [
                    Container(
                      height: 30,
                      width: 30,
                      decoration: const BoxDecoration(
                        color: Colors.red,
                        borderRadius:
                            BorderRadius.all(Radius.circular(15)),
                      ),
                    ),
                    const Positioned(
                        top: 5,
                        child: Icon(
                          Icons.clear_outlined,
                          color: Colors.white,
                          size: 20,
                        ))
                  ],
                )),
          ],
        ),
      ));
    },
    child: const Text('Show Flash Error Message')),

Next, we will add a Positioned widget. In this widget, we will add bottom is 25 and left is 20. In this child, we will add ClipRRect and inside we will add a circle icon. Additionally, we will create one more Positioned widget. In this widget, we will add a clear icon.

Simple SnackBar (Error or Confirmation)

This is the cleanest and most direct example:

ElevatedButton(
 onPressed: () {
   ScaffoldMessenger.of(context).showSnackBar(
     const SnackBar(
       content: Text('¡Este nombre de usuario no se encuentra!'),
     ),
   );
 },
 child: const Text('Mostrar mensaje'),
);

Ideal when you just want to quickly confirm something, like when I validate data before processing a payment.

Custom Floating SnackBar

Here we already added design, paddings, and a box with a rounded border:

ScaffoldMessenger.of(context).showSnackBar(
 SnackBar(
   behavior: SnackBarBehavior.floating,
   content: Container(
     padding: const EdgeInsets.all(8),
     height: 70,
     decoration: const BoxDecoration(
       color: Colors.blue,
       borderRadius: BorderRadius.all(Radius.circular(15)),
     ),
     child: const Center(
       child: Text('This Username is not found! Please try again later'),
     ),
   ),
 ),
);

I use something similar when I want the message to "float" without covering important controls.

Advanced SnackBar (Stack + Icons + Full Layout)

This is the example I use when I want a "flash message" with visual presence, especially when confirming deletions or critical errors:

ScaffoldMessenger.of(context).showSnackBar(
 SnackBar(
   backgroundColor: Colors.transparent,
   behavior: SnackBarBehavior.floating,
   elevation: 0,
   content: Stack(
     alignment: Alignment.center,
     clipBehavior: Clip.none,
     children: [
       Container(
         padding: const EdgeInsets.all(8),
         height: 70,
         decoration: const BoxDecoration(
           color: Colors.blue,
           borderRadius: BorderRadius.all(Radius.circular(15)),
         ),
         child: Row(
           children: [
             const SizedBox(width: 48),
             Expanded(
               child: Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: const [
                   Text(
                     'Oops Error!',
                     style: TextStyle(fontSize: 18, color: Colors.white),
                   ),
                   Text(
                     'This Username is not found! Please try again later',
                     style: TextStyle(fontSize: 14, color: Colors.white),
                     maxLines: 2,
                     overflow: TextOverflow.ellipsis,
                   ),
                 ],
               ),
             ),
           ],
         ),
       ),
       Positioned(
         bottom: 25,
         left: 20,
         child: ClipRRect(
           child: Icon(
             Icons.circle,
             color: Colors.redAccent,
             size: 17,
           ),
         ),
       ),
       Positioned(
         top: -20,
         left: 5,
         child: Stack(
           alignment: Alignment.center,
           children: [
             Container(
               height: 30,
               width: 30,
               decoration: const BoxDecoration(
                 color: Colors.red,
                 borderRadius: BorderRadius.all(Radius.circular(15)),
               ),
             ),
             const Positioned(
               top: 5,
               child: Icon(
                 Icons.clear_outlined,
                 color: Colors.white,
                 size: 20,
               ),
             ),
           ],
         ),
       ),
     ],
   ),
 ),
);

Perfect for screens where you want to communicate something strong without using a modal dialog.

Deep SnackBar Customization

  • Changing Colors, Borders, and Layouts
    • The SnackBar is almost like a mini-card: you can adjust color, padding, shadow, border, icons, text, and even animations.
  • Adding Icons, Actions, and Behaviors
  • I usually add:

    • success/error icons,
    • actions like "Undo",

    floating, transparent, or zero-shadow variants.

Common Errors When Using ScaffoldMessenger (and How to Avoid Them)

  • Using Incorrect Contexts
    • The classic error where the SnackBar doesn't appear. The rule is simple: always use the context that hangs off a Scaffold with access to the MaterialApp.
  • SnackBars That Don't Show
    • Happens when you navigate just before calling showSnackBar().
      With ScaffoldMessenger this no longer happens.
  • Duplicate or Accumulated Messages
    • Careful: if you don't close the previous SnackBar, it can stay in the queue.
      You can use hideCurrentSnackBar() to prevent it.

Quick FAQs About ScaffoldMessenger

  • Can it completely replace Scaffold.of(context)?
    • Yes, and it should.
  • Is it only for SnackBars?
    • No; it also manages visual information that affects the Scaffold.
  • Where should I place it?
    • Generally around your MaterialApp.

Conclusion

ScaffoldMessenger is a key tool for showing quick, reliable messages with a modern design. In my case, it's essential when I perform operations like deleting records, confirming payments, or showing critical errors, because it ensures that the message is always seen, regardless of where the user is in the navigation.

If you design UIs with good feedback, this widget is indispensable.

El siguiente paso, consiste en que conozcas como implementar una lista de elementos en Flutter con el ListView.

I agree to receive announcements of interest about this Blog.

Master ScaffoldMessenger in Flutter to display reliable SnackBar messages and avoid context errors. Learn to create custom notifications for confirmations, errors, or payments with code examples, from a simple message to an advanced design with icons and Stack.

| 👤 Andrés Cruz

🇪🇸 En español