flasktoast

Is there a way to use Bootstrap toast in Flask flashing natively?


I want to show toast messages using flash() method in Flask. I know that Bootstrap alerts work, so I used the same logic and replaced the code for alerts with toasts. But it does not seem to work for me.

app.py

@app.route('/', methods=['GET', 'POST'])
def home():
    if request.method == 'GET':
        flash('This is a demo message.')
        return render_template('home.html')

flash.html

{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
    <div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
            <strong class="me-auto">Message</strong>
            <small>11 mins ago</small>
            <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
        </div>
        <div class="toast-body">
            {{ message }}
        </div>
    </div>
</div>
{% endfor %}
{% endif %}
{% endwith %}

base.html

<html>
<head>
    ...
</head>

<body>

    {% include 'flash.html' %}
    ....
</body>
</html>

home.html

{% extends 'base.html' %}
{% block main %}
    ...
{% endblock %}

I would like to know how can I achieve this natively in Flask. If not then I will need to explore Flask-Toastr (you can suggest alternatives in case)


Solution

  • This is absolutely achievable using the flash functionality in flask, and I wouldn't recommending using something like Flask-Toastr.

    The flash functionality in flask can wrap any HTML.

    The issue with your code is in your bootstrap/html, which you can test by removing all of the flash stuff and just having:

    <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
        <div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
            <div class="toast-header">
                <strong class="me-auto">Message</strong>
                <small>11 mins ago</small>
                <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
            </div>
            <div class="toast-body">
                {{ message }}
            </div>
        </div>
    </div>
    

    You'll see that the flash doesn't show there either. I suspect the issue is that you aren't initialising the toast using javascript as required. The docs for Bootstrap Toasts are here: https://getbootstrap.com/docs/5.0/components/toasts/

    I recommend getting it working in plain HTML and then wrapping it in the flash.