Telling a screen reader "Draft saved" used to mean hiding an empty <div aria-live> somewhere in the page and writing text into it. Since September 2026 there's a proper method for that in every major browser: element.ariaNotify("Draft saved").
What it is and why it matters
Plenty of things happen in a modern interface that a sighted user notices at a glance: a badge on the cart goes from 2 to 3, a small "Saved" shows up in a corner, an icon turns red when the connection drops. Someone using a screen reader gets none of that unless the page says it out loud.
The usual tool was ARIA live regions. They work, but they come with strings attached. MDN sums it up well: live regions can only announce something after the DOM changes, and what they read is the updated content of that node. So we all ended up with the same workaround: a visually hidden node with aria-live, whose text we empty and refill just so it gets read. MDN calls that pattern "inefficient and error-prone", and anyone who has had to debug why a message is read twice, or not at all, knows what they mean.
ariaNotify() takes that workaround away. You call a method, pass it the text, and the browser hands it to the assistive technology. No helper nodes, and the message doesn't have to match anything on screen.
It became Baseline (newly available) in September 2026: Chrome and Edge 141, Firefox 150 and Safari 27.
How it works
The WAI-ARIA spec defines it as a mixin that both Element and Document include:
element.ariaNotify(announcement);
element.ariaNotify(announcement, { priority: "high" });
document.ariaNotify(announcement);
It returns undefined. The only option is priority, with two values:
"normal"(the default): it is spoken after whatever the screen reader is currently saying. It is roughly the equivalent ofaria-live="polite"."high": it interrupts and is spoken right away. It is roughlyaria-live="assertive".
It doesn't need user activation, so you can call it from a timer or when a network response arrives. That is exactly why you should use it sparingly.
In the demo above each button in the "app" calls ariaNotify() on itself. This is the helper it uses, plan B included:
function notify(el, message, priority = "normal") {
if ("ariaNotify" in el) {
el.ariaNotify(message, { priority });
} else {
// Plan B: a visually hidden aria-live region, emptied and refilled
const region = document.getElementById(priority === "high" ? "assertive" : "polite");
region.textContent = "";
setTimeout(() => { region.textContent = message; }, 50);
}
}
saveButton.addEventListener("click", (e) => {
notify(e.currentTarget, "Draft saved at 10:42.");
});
offlineButton.addEventListener("click", (e) => {
notify(e.currentTarget, "Connection lost. Your changes will sync when you are back.", "high");
});
The right-hand panel of the demo is a virtual screen reader: it can't hear what your real one says, but it draws the model MDN describes. Press "Upload 3 files" and you'll see the three messages queue up; press "Lose the connection" while it's talking and the high priority one cuts it off and goes first. Tick "Read aloud" and the browser's speech synthesis reads them so you can hear them too. If you have VoiceOver, NVDA or TalkBack running, the real announcement reaches them as well.
Which element to call it on
It isn't just a matter of taste. According to the spec, if the element is excluded from the accessibility tree the call is ignored. MDN warns that, depending on the browser, that includes containers with little semantic value such as <html> or <body>. The safest bet is to call it on the element the user just interacted with, like the button in the demo, or on document.
Language comes from the element
There's no lang parameter. The spec says the announcement inherits the language and direction of the element it is called on, so the screen reader picks the voice from the nearest lang attribute. If the message is in a different language from the page, call it from an element that declares it. In the demo, the last button has lang set to the opposite language of the page:
const note = document.createElement("div");
note.lang = "es";
document.body.append(note);
note.ariaNotify("Tu pedido está listo.");
Support and gotchas
- Feature detection:
"ariaNotify" in Element.prototype. Older Safari versions don't have it (in my tests WebKit 26.5 returnsfalse), so keep the live region as a fallback for now. The demo shows a notice and switches to it automatically. - Don't count on a queue: MDN is explicit that some screen readers read several announcements in a row, but it's not guaranteed and often only the latest one is spoken. If you have two things to say, say them in a single call.
- Live regions still win: per MDN,
aria-liveannouncements take priority overariaNotify()ones. If you mix both, the live region goes first. - macOS and ChromeOS: MDN's compatibility data notes that with VoiceOver an announcement may be dropped if another accessibility event fires at the same moment, and that on ChromeOS the method exists in Chrome but announcements are never spoken.
- Iframes: usage is controlled by the
aria-notifypermissions policy. Its default allowlist is*, so it works inside iframes unless someone blocks it, and when it is blocked the announcements fail silently. - Don't spam: not needing user activation is convenient, but every announcement interrupts someone who is listening. One message per relevant event, short and useful.
What to keep an eye on
- How each screen reader handles the queue and
highpriority. This is where behaviour will vary most for a while, so it's worth testing with NVDA, JAWS and VoiceOver rather than trusting the simulation. - When the share of browsers without support is small enough to drop the live region fallback in your project.
- The spec only defines
normalandhighfor now. If more options are added, they will show up in theAriaNotificationOptionsdictionary.