Flashing Messages
Flashing is Flask's built-in way to show a user a short, one-time message — such as "Login successful" or "Form has errors" — on the next page they visit, then automatically clear it so it never appears twice.
Learn Flashing Messages in our free Flask course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Flask course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll set a secret_key , call flash() to queue messages, and read them back with get_flashed_messages() to give users instant, friendly feedback.
A flash message is a one-time notification you store during one request and display on the next page the user loads. After it's shown once, Flask throws it away automatically.
This solves a classic problem: after a user submits a form you usually redirect them to a fresh page. A normal variable would be lost across that redirect — but a flashed message survives exactly one hop, making it perfect for "Saved!" or "Invalid password" banners.
Call flash("your message") inside a route to queue a notification. Then redirect to another page — the message waits in the session until that page reads it.
The example below flashes a confirmation after a fake "save", then redirects home. Start the server with flask run to see the banner appear once.
Notice we redirect with url_for("home") after flashing. This redirect-then-show pattern prevents the form from being resubmitted if the user refreshes.
get_flashed_messages() returns the pending messages and clears them. You usually call it in a Jinja template, but it works in routes too. Add a second argument to flash() to give each message a category like "success" or "error" .
Read categories back with get_flashed_messages(with_categories=True) , which returns pairs you can use to color the banner. Here's a typical Jinja loop you'd place in your base template:
Complete the app so it sets a secret key, flashes a success message, and reads it back. Replace each ___ .
❌ RuntimeError: The session is unavailable because no secret key was set
You called flash() without setting app.secret_key . Add a line like app.secret_key = "change-me" near where you create the app.
You're calling get_flashed_messages() more than once on the same page. Reading the messages clears them, so call it a single time — ideally in your base template only.
Build a route that checks a username and flashes a success or error message based on the result.
Lesson 15 complete — your app talks back to users!
You can set a secret_key , queue notifications with flash() , and display them once with get_flashed_messages() — even across redirects.
🚀 Up next: Building a REST API — move beyond HTML and serve structured data with proper HTTP verbs and status codes.
Practice quiz
What is a flash message?
- a permanent banner on every page
- a one-time message shown on the next request then cleared
- a logged error
- a database record
Answer: a one-time message shown on the next request then cleared. A flashed message is stored once and displayed on the next page, then discarded.
Which function queues a flash message?
- flash('Saved!')
- notify('Saved!')
- message('Saved!')
- session.flash('Saved!')
Answer: flash('Saved!'). flash('text') stores the message in the session for the next request.
Which function reads and clears pending flash messages?
- read_flashes()
- session.get_messages()
- get_flashed_messages()
- flash.get()
Answer: get_flashed_messages(). get_flashed_messages() returns the pending messages and clears them.
Why does flashing require app.secret_key?
- to encrypt the database
- to name the app
- to speed up rendering
- the messages live in the signed session cookie
Answer: the messages live in the signed session cookie. Flash messages are stored in the session, which Flask signs using secret_key.
What error occurs if you flash without setting a secret key?
- a RuntimeError about the session/secret key
- a 404
- a syntax error
- nothing, it works
Answer: a RuntimeError about the session/secret key. flash() raises a RuntimeError because Flask cannot sign the session without a secret key.
How do you add a category to a flash message?
- flash.category('success')
- flash('Saved!', 'success')
- flash('Saved!', category=True)
- flash_category('Saved!')
Answer: flash('Saved!', 'success'). A second argument like flash('Saved!', 'success') tags the message.
How do you read messages with their categories?
- get_flashed_messages(categories=1)
- get_categories()
- get_flashed_messages(with_categories=True)
- flash.with_categories()
Answer: get_flashed_messages(with_categories=True). with_categories=True returns (category, message) pairs.
Why might a flashed message appear twice?
- the secret key is wrong
- the session expired
- the message was too long
- get_flashed_messages() was called more than once on the page
Answer: get_flashed_messages() was called more than once on the page. Reading clears the messages, so calling it twice can show them again; call it once.
What pattern is flashing especially designed to support?
- redirect-then-show after a form submission
- infinite scrolling
- file uploads
- WebSocket streaming
Answer: redirect-then-show after a form submission. Flashing survives one redirect, ideal for the post/redirect/get pattern.
Where is a flashed message most commonly displayed?
- in the URL
- in a Jinja template (often the base template)
- in the console only
- in a cookie value you read manually
Answer: in a Jinja template (often the base template). get_flashed_messages() is typically looped in a Jinja template to render banners.