How to use flash messages in Symfony 3 (within the controller and the Twig view)

A system that doesn't notice the user about the things he does, simply sucks. That's the main reason why you always should implement some kind of notification system on your project, whatever the way it is e.g with JavaScript or just by adding some extra markup to your document with your favorite server language. In Symfony, you can use the useful flash system that allows you to set custom messages with a custom category in the session of the visitor.

In your Symfony controller they're pretty useful to store special messages that should be shown once the user visits a view. It's called flash message because it's stored in the session (it doesn't care if is signed in or not) and once the user visits (or is redirected to) another route of your project then it can be handled by you (shown on the view) and then it will dissappear. In short words, they vanish from the session automatically as soon as you retrieve them. This feature makes "flash" messages particularly great for storing user notifications. In this article we are going to show you how to use and display easily flash messages in your Symfony 3 application.

1. How to create flash messages

To add a flash message to the session from your controllers, you will need to use the $this->addFlash method. This method is already available on your class if it extends the Controller class of symfony. The flash method works in the following way:

Note

Remember that you can not use the addFlash method if sessions are disabled.

/**
 * Adds a flash message to the current session for type.
 *
 * @param string $type    The type
 * @param string $message The message
 *
 * @throws \LogicException
 */
protected function addFlash($type, $message)

In older versions of Symfony <2.7, it was necessary to access the container, then retrieve the session, from the session retrieve the flashBag and finally use the add method (which expects the same arguments as addFlash because $this->addFlash is simply a shortcut of the process you need to do in Symfony <2.7):

// Retrieve flashbag from the controller
$flashbag = $this->get('session')->getFlashBag();

// Add flash message
$flashbag->add($type, $message);

Although you are able to use the addFlash method from the controller, you can use the Symfony 2.7 way in recent projects as well. 

The following example shows how to add multiple flash messages within your controller with different types:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        // 1. Using the shortcut method of the controller

        // Adding a success type message
        $this->addFlash("success", "This is a success message");

        // Adding a warning type message
        $this->addFlash("warning", "This is a warning message");

        // Adding an error type message
        $this->addFlash("error", "This is an error message");

        // Adding a custom type message, remember the type is totally up to you !
        $this->addFlash("bat-alarm", "Gotham needs Batman");

        // 2. Retrieve manually the flashbag

        // Retrieve flashbag from the controller
        $flashbag = $this->get('session')->getFlashBag();

        // Set a flash message
        $flashbag->add("other", "This is another flash message with other type");

        // Render some twig view
        return $this->render("default/index.html.twig");
    }
}

Note that the given type argument is a key to a private array, that means that you can add multiple flash messages to a single category, for example multiple success and error messages:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        // 1. Using the shortcut method of the controller

        // Adding 2 success type messages
        $this->addFlash("success", "This is the first success message");
        $this->addFlash("success", "This is the second success message");

        // Adding 2 error type messages
        $this->addFlash("error", "This is the first error message");
        $this->addFlash("error", "This is the second error message");

        // Render some twig view
        return $this->render("default/index.html.twig");
    }
}

If you want to learn immediately how to show them, skip to the step 3.

2. How to remove flash messages

If you already added a flash message to the session, but for some reason don't want to display it anymore, then you need to remove it. As mentioned previously, the flash messages dissapear once they're retrieven so, to delete them, you only need to access the get method with the type of flash message as first argument without a pointer (don't store its value into a variable):

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        // Retrieve flashbag from the controller
        $flashbag = $this->get('session')->getFlashBag();

        // Set a flash message
        $flashbag->add("bat-alarm", "Gotham needs Batman");

        // Retrieves the value (that isn't being assigned to a variable)
        // and therefore is "deleted" from the flashbag
        $flashbag->get("bat-alarm");

        // Render some twig view
        return $this->render("default/index.html.twig");
    }
}

Now in the view, the bat-alarm type won't be rendered in the view anymore as it was retrieven previously (removed).

3. Display flash messages

According to the way you added the messages, there are 2 ways to display the flash messages:

New in Symfony version 3.3

The app.flashes() Twig function was introduced in Symfony 3.3.

Display per type

In Symfony > 3.3 you can provide the type of flashes that you want to display in the view as first argument in the flashes function of the app:

{% for message in app.flashes('success') %}
    <div class="flash-notice">
        {{ message }}
    </div>
{% endfor %}

In Symfony 3.X < 3.3 you can display all the messages from a predefined type in your view by providing it as first argument to the get function of the flashBag object in the session:

{% for flash_message in app.session.flashBag.get('success') %}
    <div class="alert alert-success">
        {{ flash_message }}
    </div>
{% endfor %}

You would need only to change the type and that's it.

Display all flash messages

Too lazy to filter the kind of messages in the view? Then automatize the task by settings the class of a div as the category of the flash message that will be shown on the view and then loop through all the messages of the flashbag in Twig. This example plays really nice with Bootstrap as it has the alert alert-<type> class that displays an alert div with custom colors on the page:

{% for label, messages in app.flashes %}
    {% for message in messages %}
        <div class="alert alert-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}

If you are using Symfony 3.X < 3.3, then you can iterate through the app.session.flashbag.all object as well:

{% for label, flashes in app.session.flashbag.all %}
    {% for flash in flashes %}
        <div class="alert alert-{{ label }}">
            {{ flash }}
        </div>
    {% endfor %}
{% endfor %}

Happy coding !

Become a more social person