4 min read
0%

ariaNotify()

Back to Blog
ariaNotify()

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 (like aria-live="assertive")
  • priority: "none" queues the announcement politely (like aria-live="polite")
  • notificationId deduplicates: 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.


Canvas is not supported in your browser