I have been using JAWS as my primary screen reader for over 25 years. But I test with NVDA on every single audit I run, because a significant portion of screen reader users depend on it. NVDA is free, it runs on Windows, and for many users with limited resources it is the only real option. When NVDA updates, developers need to know — because behavior changes in ways that can silently break what used to work.

In 2024, NV Access shipped several significant updates across multiple point releases. Here is what actually changed, what it means for the sites and applications you are building, and how I have updated my own testing workflow in response.

The ARIA Live Region Refinements

Live regions have always been one of the trickiest parts of ARIA to implement correctly, partly because screen reader behavior has historically been inconsistent. In 2024, NVDA shipped refined handling for aria-live regions that brings its behavior closer in line with JAWS and VoiceOver.

What Changed

Previous versions of NVDA had a known issue where rapid updates to a live region — particularly aria-live="polite" — would sometimes be skipped entirely if the updates came in faster than NVDA could queue them. This affected things like autocomplete suggestions, live search results, and status messages in single-page applications.

The 2024 updates improved the queuing behavior. NVDA now handles burst updates more gracefully, completing the current announcement before processing the next update in the queue rather than silently dropping announcements.

What You Need to Do

If you built workarounds for this behavior — specifically, if you delayed live region content injection by 300–500ms to give NVDA time to catch up — test those components again. The workaround may now cause a noticeable delay that is perceptible to the user. The better pattern in 2024 is:

<!-- Polite live region for status messages -->
<div
  role="status"
  aria-live="polite"
  aria-atomic="true"
  id="search-status"
></div>

<script>
// Update content directly — NVDA 2024 handles rapid updates correctly
function updateStatus(message) {
  const region = document.getElementById('search-status');
  // Clear first to ensure re-announcement if message is the same
  region.textContent = '';
  // Use requestAnimationFrame to allow the DOM to process the clear
  requestAnimationFrame(() => {
    region.textContent = message;
  });
}
</script>

The requestAnimationFrame trick for re-announcing the same content still applies — NVDA, like all screen readers, will not re-announce content that has not changed. Clearing the container first is still the right approach.

Modal Dialog Handling: What Broke and What Got Fixed

Modal dialogs remain one of the most consistently broken patterns I encounter in audits. In 2024, NVDA made changes to how it handles aria-modal="true" that you need to know about if you are relying on that attribute as your sole mechanism for containing focus to the dialog.

The aria-modal History Problem

For years, the accessibility community debated whether to rely on aria-modal="true" to signal to screen readers that content behind the modal should be inaccessible. NVDA's 2024 updates improved its support for aria-modal, but with an important caveat: this only works when the dialog element itself is correctly structured.

<!-- Correct: dialog element with proper attributes -->
<div
  role="dialog"
  aria-modal="true"
  aria-labelledby="dialog-title"
  id="confirmation-dialog"
>
  <h2 id="dialog-title">Confirm action</h2>
  <p>Are you sure you want to delete this item?</p>
  <button type="button">Delete</button>
  <button type="button">Cancel</button>
</div>

<!-- Also: inert the background content in JS -->
<script>
// Do NOT rely on aria-modal alone for background inertness
// Use the inert attribute on everything behind the modal
document.getElementById('main-content').setAttribute('inert', '');
document.getElementById('site-header').setAttribute('inert', '');
</script>

My testing in late 2024 confirmed: aria-modal="true" alone is still not reliable enough across all NVDA versions to be your sole focus containment strategy. Use it — but back it up with the inert attribute and a JavaScript focus trap.

Browse Mode vs. Focus Mode: The Developer's Most Common Confusion

NVDA operates in two primary modes: browse mode (also called virtual cursor mode) and focus mode. Understanding this distinction is essential to testing correctly, and the 2024 updates touched on how mode switching is triggered.

Browse Mode

Browse mode is the default. In browse mode, NVDA presents the page as a linear virtual buffer. Users navigate with arrow keys, moving through text, headings, links, and other content. Single-letter navigation shortcuts work in this mode: pressing H moves to the next heading, B moves to the next button, and so on.

Focus Mode

Focus mode activates automatically when the user tabs to an interactive element — a text field, a custom widget, a combobox. In focus mode, keystrokes are passed directly to the focused element rather than being intercepted by NVDA's virtual cursor. This is why form controls work as expected when navigating with a screen reader.

What Changed in 2024

The 2024 updates refined automatic mode switching for custom widgets. If you build a widget with role="application" — which forces focus mode at all times — you need to be aware that NVDA now handles this more strictly. Any widget with role="application" that does not implement complete keyboard interaction internally will leave users stranded.

My recommendation: avoid role="application" unless you are building a genuinely application-like widget (a rich text editor, a spreadsheet interface) and you have implemented every ARIA Authoring Practices pattern correctly. For simpler interactive components, use the appropriate widget role instead.

Updated Testing Workflow for NVDA in 2024

Here is the exact workflow I use when I test a site or component with NVDA:

Environment Setup

The Six Core Tests

  1. Page title and landmark structure. On page load, NVDA should announce the page title. Open the Elements List (NVDA+F7) and check that your landmark regions are correctly labeled and make logical sense.
  2. Heading hierarchy. Navigate by headings (H) and verify the hierarchy is logical. NVDA+F7 → Headings shows the full list.
  3. Form controls. Tab through every form field and verify that NVDA announces the label, the control type, and the current value or state. Test error messages — they must be announced, not just visually displayed.
  4. Interactive widgets. Tab to each custom widget and verify that entering focus mode (automatic or via Enter) works as expected, and that all widget keyboard interactions function correctly.
  5. Live regions. Trigger every dynamic content update and verify that NVDA announces it. Specifically test: autocomplete suggestions, alert messages, status updates, and content loaded after user actions.
  6. Modal dialogs. Open every modal on the page and verify: focus moves into the dialog on open, Tab cycles within the dialog only, Escape closes the dialog and returns focus to the trigger element.

The Failures I Find Most Often With NVDA in 2024

After running dozens of audits in 2024 with the updated NVDA versions, these are the failure patterns I find most consistently:

Custom Buttons That Are Not Buttons

A div styled as a button with a click handler, no role="button", no keyboard activation. NVDA in browse mode will read it as generic content. NVDA in focus mode will not reach it at all. The fix is always the same: use a real <button> element.

Unlabeled Icon Buttons

Icon-only buttons with no accessible name — no aria-label, no visually hidden text, no title attribute. NVDA announces these as "button" with no context. I find this on close buttons, social share buttons, and navigation arrows constantly.

<!-- Wrong -->
<button type="button">
  <svg aria-hidden="true">...</svg>
</button>

<!-- Correct -->
<button type="button" aria-label="Close dialog">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>

Dynamic Content Updates Without Live Regions

A filter panel updates results, a shopping cart count changes, a success message appears — and none of it is announced by NVDA because there is no live region. The DOM updated visually, but from a screen reader perspective, nothing happened.

What Developers Should Take From This

The most important thing I can tell you about testing with NVDA in 2024 is this: run it yourself. Not just automated testing, not just running axe-core — actual manual testing with NVDA running, speech viewer open, and your hands on the keyboard.

Twenty minutes of manual NVDA testing will surface failures that no automated tool will catch. The live region timing issues, the focus management gaps, the unlabeled dynamic content — these are all invisible to automated scanners and completely visible to any screen reader user navigating your site.

If you have never used NVDA before, start with the NV Access documentation and practice on a few well-known sites before testing your own. The learning curve is shorter than you expect, and the insight you gain is irreplaceable.

Need a real accessibility audit?

Not a Lighthouse score — a thorough WCAG 2.2 AA audit with manual JAWS testing and code-level remediation guidance your developers can actually use.

Schedule a Free Consultation