vercel / vercel/next.js

Accessibility (a11y): next-route-announcer only announces title changes, H1/path fallbacks never used

Open
#86,660 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Linking and Navigating
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/Unit2795/next-announcer-issue

To Reproduce
  1. Ensure you have a screen reader and node.js installed.
  2. Clone the repository.
  3. Install dependencies using npm install.
  4. Run the development server using npm run dev.
  5. Start your screen reader
  6. Open the application in a web browser, you should see the homepage with a few link buttons.
  7. Click on the "Test" link to navigate to the /test page
  8. Observe that the screen reader announces the navigation change.
  9. Click on the "Test with Subpath" link to navigate to the /test/subpath page.
  10. Observe that the screen reader does not announce the navigation change.
Current vs. Expected behavior

Current:

  1. If there is a document title, check if it changed. If it didn't change, do not announce a change.
  2. Fallback to <h1> only occurs if there is no page title at all. (IE: document.title is undefined, null, or falsy.)
  3. Since pages usually have a title, the H1 fallback path is effectively a no-op.
  4. The path is never announced.

Expected:

  1. If document title changed, announcer reads new title. If unchanged, proceed to next step:
  2. If h1 changed, announcer reads new h1. If unchanged, proceed to next step:
  3. If URL path changed, announcer reads URL path
Provide environment information
Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
  Available memory (MB): 65450
  Available CPU cores: 24
Binaries:
  Node: 25.2.1
  npm: 11.6.2
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 16.1.0-canary.4 // Latest available version is detected (16.1.0-canary.4).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A
Which area(s) are affected? (Select all that apply)

Linking and Navigating

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local), Vercel (Deployed), Other (Deployed)

Additional context

The next-route-announcer accessibility live region will generally only announce route changes when the document.title changes. It will not announce the title change only when there is no title at all (document.title is undefined, null, or falsy), but most sites generally have a title. So the logic for announcing based on an h1 or path is essentially a no op.

https://github.com/vercel/next.js/blob/737ddf775b491fb123fde41cc21a6a2d7ad599b9/packages/next/src/client/components/app-router-announcer.tsx#L48-L66

Based on the documentation (Next.js - Architecture: Accessibility), I would anticipate that the behavior should be cascading like I described in my expected behavior. What's more, the documentation for the app router mentions that the final fallback is to announce the path, but no such logic to announce the path exists for the app-router-announcer.

Sites should provide a unique title per page, according to WCAG SC 2.4.2. However, there could plausibly be minor state variations in the path. (IE: /product?sort=price vs /product?sort=rating OR /order/dinein vs /order/carryout). In this case, when the document title does not change, no announcement will be made by the next-route-announcer. This is not accessible; because a navigation has still occurred, UI may have changed slightly, focus may have shifted, and the user needs to be made aware of that.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/next/src/client/components/app-router-announcer.tsx, especially the linked lines, and reproduce the behavior in the linked next-announcer-issue project with a screen reader. Done means route changes use the documented title, h1, and path fallback sequence, including navigation where the title is unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, next.js, react
Domain
accessibility, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.