
ariaNotify()
ariaNotify() is a new JavaScript API that sends an accessible announcement directly to screen readers — no live region markup, no invisible DOM nodes, no timing hacks.
document.ariaNotify("3 results found", { priority: "important" }); Screen readers announce the string immediately. Nothing needs to exist in the DOM.
The Problem with Live Regions
The existing approach uses aria-live regions — empty elements that the assistive technology watches for mutations:
<div aria-live="polite" aria-atomic="true" class="sr-only" id="announcer"></div> // Timing is fragile — needs a tick delay for re-announcements
announcer.textContent = "";
requestAnimationFrame(() => {
announcer.textContent = "Item added to cart";
}); This pattern has well-known failure modes: double-announcements, missed updates when DOM churn is fast, and inconsistent behavior across screen reader / browser combinations.
ariaNotify() API
element.ariaNotify(message, options); Parameters:
interface AriaNotifyOptions {
priority?: "important" | "none"; // default: "none"
interrupt?: "all" | "pending" | "none"; // default: "none"
notificationId?: string; // deduplicate notifications
} priority: "important"interrupts the current reading queue (likearia-live="assertive")priority: "none"queues the announcement politely (likearia-live="polite")notificationIddeduplicates: a new call with the same ID replaces the pending one
Deduplication with notificationId
// Typing in a search box — only the last result count matters
function onSearchUpdate(count) {
document.ariaNotify(`${count} results`, {
priority: "none",
notificationId: "search-count",
});
} Rapid calls with the same notificationId coalesce — screen readers get the final value, not every intermediate one.
Replacing the Live Region Pattern
// Before
function announce(msg) {
liveRegion.textContent = "";
requestAnimationFrame(() => {
liveRegion.textContent = msg;
});
}
// After
function announce(msg, urgent = false) {
document.ariaNotify(msg, {
priority: urgent ? "important" : "none",
});
} No DOM element needed. No timing gymnastics.
Scoping to an Element
ariaNotify lives on Element, not just document, so you can scope announcements to a widget:
const grid = document.querySelector("[role=grid]");
grid.ariaNotify("Row deleted", { priority: "none" }); Screen readers that support context-aware announcements can present this differently from a global document announcement.
Use Cases
- Search result counts updating as the user types
- Toast / snackbar messages
- Async operation completions (“File uploaded”)
- Live score or status updates
- Form validation summaries
Feature Detection
if ("ariaNotify" in document) {
document.ariaNotify("Page loaded");
} else {
// Fall back to live region
} ariaNotify() is in active development in Chrome and is part of the ARIA specification. Check the ARIA Working Group repo for the latest status.









