WCAG 4.1.3 Status Messages — Testing Guide
WCAG 4.1.3 Status Messages (Level AA) requires that status messages — alerts, toasts, loading indicators, success confirmations — are announced to assistive technologies without the user needing to ex
WCAG 4.1.3 Status Messages (Level AA) requires that status messages — alerts, toasts, loading indicators, success confirmations — are announced to assistive technologies without the user needing to explicitly find them. This criterion specifically addresses content that changes dynamically.
What it requires
When the page updates with new status information:
- The update is programmatically exposed (ARIA
role="alert"orrole="status"oraria-live) - The update is announced to screen readers without moving focus
- The announcement is appropriate in urgency (alerts vs status vs polite updates)
Common violations
1. Toast appears, disappears silently
Success toast "Saved" appears for 3 seconds, fades. Screen reader never announces it. User does not know save succeeded.
Fix:
<div role="status" aria-live="polite">Saved</div>
2. Form error inserted without announcement
Submit form → validation error appears in red text below field. Screen reader silent. User submits again, same error.
Fix:
<div aria-live="assertive" role="alert">Email format invalid</div>
3. Progress indicator not announced
Uploading; progress bar fills. Screen reader does not announce progress.
Fix:
<div role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"
aria-valuetext="40 percent uploaded">
Update aria-valuenow / aria-valuetext as progress changes.
4. Dynamic content add without announcement
Chat message arrives; appended to chat log. Screen reader oblivious.
Fix:
<div role="log" aria-live="polite">
<!-- appended messages -->
</div>
5. Navigating to new route, no announcement
SPA route change; title updates. Screen reader silent.
Fix: Route change → focus moves to of new page, OR announce via live region.
ARIA live region roles
role="alert" / aria-live="assertive"
Interruptive. Announces immediately, interrupting whatever screen reader is saying. Use sparingly — errors, critical warnings.
role="status" / aria-live="polite"
Announces when screen reader is idle. Use for most status updates — success toasts, loading complete, general info.
role="log"
Message-log-style updates (chat, notifications feed).
role="progressbar"
Progress indicators with value.
role="timer"
Count-up / count-down timers.
Testing
Automated
- axe-core checks for dynamic content changes
- Some tools do not catch this well — dynamic nature is hard to test statically
Manual
- Screen reader (NVDA, JAWS, VoiceOver, TalkBack) on
- Trigger every status: save, error, load, progress
- Does screen reader announce each?
Script
// Playwright
const region = page.locator('[role="status"]');
await page.click('button#save');
await expect(region).toContainText('Saved');
// Programmatic check, not actual SR announcement — still catches common regressions
Fix patterns
React
function StatusRegion({ message }) {
return <div role="status" aria-live="polite">{message}</div>;
}
// Controlled by state; updates trigger announcement
Vue
<div role="status" aria-live="polite">{{ statusMessage }}</div>
Native mobile
- Android:
setAccessibilityLiveRegion(LIVE_REGION_POLITE) - iOS:
UIAccessibility.post(notification: .announcement, argument: "message")
Do not
- Move focus on every status change — disorienting
- Announce everything — too chatty for screen reader users
- Use
alert()browser dialog — interruptive and ugly
Distinguishing message types
- Alert: critical, immediate action needed (errors, data loss warnings)
- Status: informational, no action needed (saved, loaded, loading complete)
- Log: sequential messages over time (chat, event feed)
- Progress: ongoing task completion
Match the role to the purpose. Do not use role="alert" for a success toast.
How SUSA tests 4.1.3
SUSA's accessibility_user persona triggers state changes and verifies:
- Live regions exist
- Content updates within the regions trigger announcements
- Progress indicators have proper ARIA
Flags:
- Toasts without
role="status"oraria-live - Errors shown visually without announcement
- Chat / feed updates without
role="log" - Progress bars missing
role="progressbar"or value
susatest-agent test https://myapp.com --persona accessibility_user --wcag-level AA
Common mistakes
- Setting
aria-liveon a whole page: announces too much - Adding
aria-liveafter the content is inserted: announcement does not fire - Frequently updating live region: announcements queue and become unmanageable
- Silent error: validation failure visible but not announced
- Overloading
role="alert": routine messages feel interruptive
Status messages are the feedback loop. For screen reader users, they are the entire feedback loop. Get them right.
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free