2.4.9 Link Purpose (Link Only)

WCAG 2.2 · 2.4.9 AAA Operable

What it requires

A mechanism must be available to determine the purpose of each link from the link text alone — except where the link's purpose would be ambiguous to users in general. This is the stricter sibling of 2.4.4 Link Purpose (In Context), which lets you lean on surrounding text, the sentence, list item, table cell, or heading. At Level AAA the link text must stand on its own: someone reviewing a flat list of all the links on the page should still understand where each one goes.

  • Screen-reader users who navigate by pulling up an out-of-context list of links — generic text like “click here” or “read more” becomes meaningless.
  • Users with cognitive disabilities who benefit from clear, self-explanatory targets and are confused by repeated, identical link text.
  • Voice-control users who speak a link's visible text to activate it; unique, descriptive text makes commands unambiguous.
  • Sighted users scanning quickly, who rely on link text to decide where to click without reading the surrounding paragraph.

How to detect it

Ways to check Link Purpose (Link Only)
Check What to look for
Manual review Read each link's text in isolation. Could you tell its destination without the surrounding sentence? Flag “here”, “more”, “read more”, “details”, bare URLs.
Screen reader Open the links list (e.g. NVDA Insert+F7, VoiceOver rotor). Every entry should describe its own target; watch for duplicate or vague labels.
Keyboard Tab through links; the focused link's accessible name should reveal its purpose on its own.
Zoom / reflow At 200%+ context can scroll out of view, so self-describing text matters even more — confirm nothing relies on adjacent content.
Automated tools axe and similar flag empty links and some generic phrases, but cannot judge whether text truly conveys purpose — this needs human review.

How to fix it

  1. Write link text that names the destination or action: “Download the 2025 annual report (PDF)” rather than “Download”.
  2. Replace generic phrases like “click here” / “read more” with descriptive text.
  3. If a short visible label must stay, extend the accessible name with visually hidden text or aria-label so the full purpose is in the link itself.
  4. Make repeated links unique when they go to different targets.
<!-- Visible label kept short; full purpose in the link -->
<a href="/reports/2025.pdf">
  Read more<span class="visually-hidden"> about the 2025 annual report (PDF)</span>
</a>

Copy-paste tests

Automated coverage

The axe-core rule identical-links-same-purpose flags failures of this criterion. Run it via the axe DevTools browser extension or axe-core in CI. Automated tools only catch some failures — vague but non-identical text still needs human review.

Run this in the browser console

find-vague-links.js
// Read-only: surfaces links whose text alone may not convey purpose.
const vague = /^(click here|here|read more|more|details|learn more|link)$/i;
const suspects = [...document.querySelectorAll('a[href]')].filter(a => {
  const name = (a.getAttribute('aria-label') || a.textContent).trim();
  return name === '' || vague.test(name) || /^https?:\/\//i.test(name);
});
suspects.forEach(a => { a.style.outline = '2px solid red'; });
console.table(suspects.map(a => ({ text: a.textContent.trim(), href: a.getAttribute('href') })));

What to check manually: read each flagged link's text out of context and confirm it names its destination; verify links sharing identical text actually go to the same place — no script can judge whether wording truly conveys purpose.