Skip to main content

Toast and status after submit: using role="status"

Published: •5 min read•navable Team
FormsStatus messagesScreen readersARIAWCAG

You add an item to your cart. A brief “Added” message appears at the bottom of the screen while focus stays on the button. Someone who cannot see that message needs feedback too. A visible line of text alone does not ensure they receive it.

For ordinary success and result messages, use an existing region with role="status" and update its text after the action. Test with a screen reader to find out whether the announcement is understandable and arrives at a useful time.

What feedback does the action need?

WCAG 4.1.3 Status Messages covers information about results, waiting, progress or errors that appears without a change of context. “12 results” after a search is an example. The entire new list of results is not automatically a status message.

Choose feedback for the task:

  • Saved, item added, result count changed: role="status" is usually appropriate. Its implicit polite live setting is intended to avoid unnecessary interruptions to current output.
  • An important, time-sensitive warning: Consider role="alert". Its implicit live setting is assertive. Use it sparingly; an ordinary success message does not need this urgency.
  • A form needs correcting: Associate errors with their fields and plan the route to them. A focused error summary may help. That is a decision about the interaction, rather than a reason to turn every field error into an alert.

WAI-ARIA 1.2 defines these roles. The W3C alert pattern does not move focus for a warning alone. When immediate action is required, design an appropriate dialog interaction.

Why can a newly inserted message stay silent?

This React pattern creates the region and its message at the same time:

{saved && <p role="status">Settings saved.</p>}

The screen reader first has to discover the region. Relying on its initial content to count as an update is risky. TetraLogical explains this insertion sequence and reports its own browser/screen-reader tests from 2024. For alert, WAI-ARIA recommends a dedicated event when the alert is created, if the operating system allows it. That is not a reason to use alert for success messages.

The synthetic example below inserts a new, populated status region every time you add an item. Try it with your browser and screen reader.

Risky pattern: insert a populated status region

Local simulation. Nothing is ordered, sent or stored.

Teaching example: notebook

JavaScript enables the examples.

Each action inserts a new status region with its text already inside. An announcement may be missed. Actual screen-reader speech has not been tested here.

Pattern check: The region does not exist before the first action. It therefore fails the first test step in W3C technique ARIA22. This describes its structure; an actual missed announcement has not been demonstrated here.

Keep the region and change its text

Render the empty region with the page. This local simulation updates it after adding an item. For a real save, announce success only after the save has completed successfully:

import { useState } from "react";

function CartStatus() {
  const [count, setCount] = useState(0);
  return (
    <>
      <button type="button" onClick={() => setCount(value => value + 1)}>
        Add an example item
      </button>
      <p role="status" aria-atomic="true">
        {count > 0 ? `Example cart: ${count} items.` : ""}
      </p>
    </>
  );
}

aria-atomic="true" treats the complete message as one unit of output. ARIA22 recommends setting it explicitly because support varies. Do not hide the empty region with display: none or hidden when it should already be ready for updates.

Recommended pattern: update an existing status region

Local simulation. Nothing is ordered, sent or stored.

Teaching example: notebook

JavaScript enables the examples.

The empty status region exists before the action. Only its text changes. Test the actual announcement with your browser and screen reader; speech output has not been verified here.

Pattern check: The empty status region exists before the action and receives the text afterwards. It passes the structural test steps illustrated here from ARIA22. A structural pass proves neither spoken output nor accessibility of the whole form.

Both examples keep focus on the add button and retain the message until the next action or reset. The item count changes on each action. This does not test whether an identical message is spoken after repeated saves. Check that separately: an unchanged string may not produce a new content change.

How long should a toast remain?

For a temporary message, check whether the information or action remains available afterwards. WCAG 2.2.1 explains the distinction: a temporary notification may be acceptable when the same information or function remains available elsewhere without a time limit. Without that alternative, the time limit needs to meet the criterion unless an exception applies.

A cart can keep its updated contents visible. If a toast offers “Undo”, keep the same action available elsewhere after the toast disappears. Otherwise, the time limit must meet WCAG 2.2.1, for example through a way to turn it off, adjust it or extend it, unless an exception applies. Briefly making the button keyboard-accessible is not enough on its own.

What do you check in the browser and with a screen reader?

Start with the keyboard interaction, then repeat it with a screen reader running:

  1. Reload the page. Does the empty status region already exist?
  2. Trigger the action. Does the right message appear while focus stays on the trigger?
  3. Trigger it again. Test changed messages and identical messages separately.
  4. Record the words you hear, any delay and interruptions. Include the browser, screen reader and their versions.
  5. For temporary toasts, check while the message is visible and after it disappears. Are the same information and any offered actions, such as “Undo”, still available without time pressure? If not, does the time limit meet WCAG 2.2.1?

Scan the initial and message states separately, for example locally using the developer workflow. A DOM scan can examine roles and other machine-evaluable properties. It cannot hear speech output. A scan without findings does not rule out a missed or repeated announcement.

These examples demonstrate two insertion sequences, rather than a current support matrix for NVDA, JAWS or VoiceOver. Our own speech tests remain outstanding. The forms guide covers labels and associated field errors.

Further reading and sources