Skip to main content
Navigation issues disorient users, cause accidental data loss, and make it difficult to understand where links lead. They affect all users, but are particularly impactful for screen reader users who rely on link text to decide whether to follow a link.

no-confirmation-critical-action

Critical

What it is

Buttons or links that trigger destructive or irreversible actions — such as deleting an account, removing data, cancelling a subscription, or clearing content — execute immediately on click with no confirmation step.

Why it matters

Accidental clicks on destructive buttons can cause permanent data loss. A user who accidentally clicks “Delete Account” should have a chance to cancel before the action completes. This is both a usability requirement and a user trust concern.

How QAOS detects it

The agent identifies buttons and links with text suggesting a destructive action (delete, remove, clear, cancel, destroy, erase, purge) and clicks them, observing whether a confirmation dialog or confirmation step appears before the action executes.

Examples

<!-- No confirmation — immediate delete -->
<button onclick="deleteAccount()">Delete Account</button>

<!-- Correct: triggers confirmation dialog first -->
<button onclick="confirmDelete()">Delete Account</button>
<!-- which shows: -->
<dialog>
  <p>Are you sure? This action cannot be undone.</p>
  <button onclick="deleteAccount()">Yes, delete my account</button>
  <button onclick="closeDialog()">Cancel</button>
</dialog>

How to fix

For any action that is irreversible or has significant consequences, require an explicit confirmation step before executing:
  1. Show a modal dialog with a clear description of what will happen
  2. Require the user to click a distinct “confirm” button
  3. Offer a prominent “cancel” option
  4. For especially destructive actions, require typing a confirmation phrase (e.g., the account name)

High WCAG 2.4.6

What it is

Link text is generic and gives no indication of the link’s destination or purpose — phrases like “click here”, “read more”, “learn more”, or placeholder-like text.

Why it matters

Screen reader users often navigate by cycling through links on a page. If every link says “click here”, they cannot determine which link leads where without reading the surrounding context. This makes navigation extremely inefficient.

How QAOS detects it

The agent scans anchor elements for text that matches generic patterns: “click here”, “read more”, “here”, “link”, “more”, or text that is completely unintelligible (underscores, gibberish).

Examples

<!-- Unclear -->
<a href="/about">Click here</a>
<a href="/terms">Read more</a>
<a href="/contact">______</a>

<!-- Correct: descriptive link text -->
<a href="/about">About our company</a>
<a href="/terms">Read our Terms of Service</a>
<a href="/contact">Contact the support team</a>

How to fix

Write link text that describes the destination or action. The link text should make sense out of context:
<!-- If you must use "read more", provide accessible context -->
<a href="/blog/post-1">
  Read more <span class="sr-only">about our Q4 results</span>
</a>

inconsistent-navigation

High WCAG 3.2.3

What it is

The main navigation structure changes between pages of the same website — items appear in different orders, links appear on some pages but not others, or the navigation layout changes across sections.

Why it matters

Consistent navigation is a fundamental usability expectation. Users build a mental model of your navigation structure after visiting a few pages. When navigation changes, users lose their orientation and spend cognitive effort re-learning the layout instead of accomplishing their goal. Screen reader users are particularly affected — they often navigate by landmark regions (<nav>), and changing navigation structures make each page feel like a new website.

How QAOS detects it

The agent follows navigation links to multiple pages and compares the navigation structure — checking for order changes, missing items, or structural differences between pages.

How to fix

Implement a shared navigation component that renders identically on every page. In React/Next.js, this is typically a layout component:
// _app.jsx or layout.jsx
export default function Layout({ children }) {
  return (
    <>
      <Navigation /> {/* same component on every page */}
      <main>{children}</main>
    </>
  )
}
If different pages genuinely need different navigation (e.g., a separate admin section), ensure the structure within each section is internally consistent.
High WCAG 2.1.1

What it is

A custom (non-native) dropdown component does not support ArrowDown/ArrowUp keyboard navigation between options. Users must use a mouse to select an option.

Why it matters

Keyboard-only users, screen reader users, and users with motor impairments rely on arrow key navigation in list components. A custom dropdown that only responds to mouse clicks is inaccessible to them.

How QAOS detects it

The agent identifies custom dropdown components (e.g., <div role="listbox"> or custom comboboxes) and checks whether they have keyboard event handlers for arrow key navigation.

Examples

<!-- Non-native dropdown with no keyboard handler — inaccessible -->
<div role="listbox">
  <div role="option" onclick="select('US')">United States</div>
  <div role="option" onclick="select('CA')">Canada</div>
</div>

How to fix

Implement the ARIA Listbox keyboard pattern — ArrowDown/ArrowUp to move focus, Enter or Space to select, Escape to close:
listbox.addEventListener('keydown', (e) => {
  if (e.key === 'ArrowDown') focusNext()
  if (e.key === 'ArrowUp') focusPrev()
  if (e.key === 'Enter' || e.key === ' ') selectFocused()
  if (e.key === 'Escape') closeDropdown()
})
Alternatively, use a native <select> element which provides keyboard navigation for free.
Medium WCAG 4.1.2

What it is

An <a> element has no visible text and no aria-label, making it invisible to screen reader users. Common cases include icon-only links or image links where the image has no alt text.

Why it matters

Screen readers announce links by their text content. An empty link is announced as “link” with no destination — completely useless for navigation. Users cannot know where the link leads or whether to follow it.

How QAOS detects it

The agent scans anchor elements for those with no visible text content and no accessible name via aria-label, aria-labelledby, or an image with a non-empty alt.

Examples

<!-- Empty link — no text, no aria-label -->
<a href="/home"></a>

<!-- Image link with no alt — screen reader skips the description -->
<a href="/about"><img src="logo.png"></a>

<!-- Correct: accessible name provided -->
<a href="/home" aria-label="Go to homepage"></a>
<a href="/about"><img src="logo.png" alt="About Acme Corp"></a>

How to fix

Ensure every link has a meaningful accessible name — either as visible text, image alt text, or aria-label.
Low WCAG 3.2.2

What it is

A link with target="_blank" opens in a new tab or window without informing the user that this will happen.

Why it matters

Unexpected new tabs disorient users, especially screen reader users who rely on the browser back button. Users who don’t expect a new tab may think the application has navigated away and lose their place in the original page.

How QAOS detects it

The agent scans anchor elements for target="_blank" and checks whether any indication is given to the user (text, icon, or aria-label mentioning the new tab behavior).

Examples

<!-- Opens new tab with no warning -->
<a href="https://example.com" target="_blank">Read more</a>

<!-- Correct: visual and accessible warning -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  Read more <span aria-label="(opens in new tab)"></span>
</a>

How to fix

Indicate new-tab behavior visually and in accessible text. Always add rel="noopener noreferrer" to prevent the opened page from accessing window.opener:
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  Terms of Service <span class="sr-only">(opens in new tab)</span>
</a>

Low

What it is

A link points to a downloadable file (PDF, DOCX, ZIP, etc.) but gives no indication of the file type or size. Users who click it may be surprised by a download prompt or a slow transfer.

Why it matters

Users on slow connections, mobile data, or screen readers need to know what they’re getting before they click. A link that triggers an unexpected download or opens a large file wastes time and can consume mobile data allowances.

How QAOS detects it

The agent scans anchor elements whose href ends in a file extension (.pdf, .docx, .zip, .xlsx, etc.) and checks whether any file-type or size information accompanies the link.

Examples

<!-- No file-type warning -->
<a href="/files/annual-report.pdf">Annual Report</a>

<!-- Correct: file type and size indicated -->
<a href="/files/annual-report.pdf">Annual Report (PDF, 2.4 MB)</a>

How to fix

Include the file type and size inline with the link text, or via an icon:
<a href="/files/report.pdf">
  Annual Report <span class="file-info">(PDF, 2.4 MB)</span>
</a>