WCAG Success Criteria · Level AAA
WCAG 2.4.9: Link Purpose (Link Only)
WCAG 2.4.9 requires that the purpose of every link can be determined from the link text alone, without relying on surrounding context. This stricter AAA criterion ensures all users — especially screen reader users navigating by links — can understand where a link leads without reading the entire page.
- Level AAA
What This Rule Means
\nWCAG 2.4.9 — Link Purpose (Link Only) is a Level AAA success criterion under WCAG 2.1 and 2.2. It requires that the purpose of each link can be determined from the link text alone. Unlike its AA counterpart, WCAG 2.4.4 (Link Purpose — In Context), which permits link purpose to be inferred from surrounding context such as a heading, paragraph, or table cell, 2.4.9 is significantly stricter: the link text itself must be fully self-descriptive, with no reliance on surrounding content whatsoever.
\nThe criterion applies to all hyperlinks created with the <a> element, as well as any interactive element that carries an accessible name and behaves as a link. This includes image links (where the image's alt attribute or an aria-label provides the accessible name), button-styled links, and SVG-based links. The accessible name of the link — computed from its visible text, aria-label, aria-labelledby, or image alternative text — must on its own communicate where the link goes or what it does.
What counts as a pass: A link passes 2.4.9 when a user who reads only the link text — and nothing else on the page — can confidently understand the link's destination or function. For example, a link reading "Download the 2024 Annual Accessibility Report (PDF, 2.4 MB)" passes because all relevant information is contained within the link text itself. A link reading "Read the full article: How to Write Accessible Link Text" also passes. An image link with alt='View pricing plans' passes because the alt text is fully descriptive.
What counts as a fail: Links whose text is "click here," "read more," "learn more," "this," "here," or any other phrase that is meaningful only in context fail this criterion. Similarly, a link wrapping an image whose alt attribute is empty or absent, leaving the link with no accessible name, fails. Links that use aria-label or aria-labelledby but whose computed accessible name is still vague also fail.
Official exceptions: WCAG explicitly notes one exception — where the purpose of the link is intentionally ambiguous to all users, not just those with disabilities. For example, a teaser link in a mystery game that reads "Proceed" (where ambiguity is the intentional design) would not be considered a failure, provided the ambiguity applies universally. This exception is narrow and should not be used as a loophole for poor link text practices.
\n\nWhy It Matters
\nMeaningful link text is one of the most impactful accessibility improvements a website can make. The populations most directly affected by vague link text are screen reader users, users who navigate by keyboard, users with cognitive disabilities, and users of voice control software.
\nScreen reader users — typically people who are blind or have severe low vision — frequently navigate a page by pulling up a list of all links. Popular screen readers such as NVDA, JAWS, and VoiceOver all offer this feature, which extracts every link's accessible name and presents them as a standalone list. When links read "click here," "read more," or "details," this list becomes a series of identical, meaningless entries. The user has no way to determine which link to activate without reading the surrounding content for each one — a slow, frustrating, and often impossible task, especially on pages with dozens of links.
\nAccording to the World Health Organization, approximately 2.2 billion people worldwide have some form of vision impairment, of whom at least 1 billion have a condition that could have been prevented or has yet to be addressed. Even among users without visual disabilities, motor-impaired users who rely on switch access or voice navigation (using tools like Dragon NaturallySpeaking) benefit enormously from descriptive link text because they can activate a link directly by speaking or selecting its name. Cognitive disability groups — including users with attention deficits, memory impairments, or reading difficulties — also benefit because clear link labels reduce cognitive load and the need to re-read context.
\nConsider a real-world scenario: a Turkish citizen visiting the website of a public hospital to book an appointment. The page has three service buttons, each containing the phrase "Randevu Al" (Book Appointment) with no further context in the link text. A blind user opening their screen reader's link list sees "Randevu Al," "Randevu Al," and "Randevu Al" — three indistinguishable options. They cannot determine which link is for cardiology, which is for general practice, and which is for radiology without navigating back to context. Meeting WCAG 2.4.9 would require each link to read "Randevu Al — Kardiyoloji," "Randevu Al — Genel Pratisyen," and "Randevu Al — Radyoloji," making the purpose unambiguous from the link text alone.
\nBeyond accessibility, descriptive link text carries significant SEO value. Search engine crawlers weight anchor text when indexing pages, and descriptive links improve the relevance signals for both the source page and the destination page. Replacing generic anchor text with meaningful phrases improves discoverability and reduces bounce rates, benefiting all users.
\n\nRelated Axe-core Rules
\nWCAG 2.4.9 requires manual testing because automated tools cannot determine meaning or intent — they can flag the absence of an accessible name, but they cannot judge whether a given accessible name is sufficiently descriptive.
\n- \n
- Manual testing required — link-name (axe rule): The axe-core
link-namerule detects links that have no accessible name at all (for example, an<a>element with no text content, noaria-label, noaria-labelledby, and no image with a non-emptyaltattribute). While this rule catches completely empty links, it cannot evaluate whether the accessible name that does exist is meaningful. A link reading "here" will pass the automatedlink-namerule because it technically has an accessible name — but it fails WCAG 2.4.9 because that name is not self-descriptive. This is precisely why 2.4.9 is flagged as requiring manual review: a human must read each link label and judge whether it communicates purpose in isolation. \n - Manual testing required — identical-links-same-purpose: Axe-core includes a rule that flags sets of links with identical accessible names but different destinations. This is a heuristic that surfaces potential 2.4.9 violations — for instance, multiple "Read More" links pointing to different articles. However, even this rule requires human confirmation, because identical names pointing to the same destination are not a violation. The rule raises candidates for review, not definitive failures. \n
- Why automation is insufficient: Natural language understanding is required to assess link purpose. An automated tool can compute that a link's accessible name is the string "details" but cannot know that this string fails to describe a destination. Similarly, a tool cannot assess whether "View" is adequate (perhaps it is, in a very specific narrowly scoped interface) or whether "View the Q3 Financial Statement" is better. Human judgment, ideally combined with screen reader testing, is the only reliable method. \n
How to Test
\n- \n
- Automated scan baseline: Run axe DevTools (browser extension) or Lighthouse on the target page. In axe DevTools, look for any violations of the
link-namerule — these represent links with no accessible name at all and are guaranteed failures of 2.4.9. Export the results and note all flagged links. This step does not complete your 2.4.9 audit; it only identifies the lowest-hanging failures. \n - Generate a links list with a screen reader: Open the page in Firefox with NVDA installed. Press Insert + F7 (NVDA's Elements List shortcut) and select "Links" from the dialog. Review the full list of link labels. Ask yourself: could a user reading only this list understand the destination or function of every link? Repeat this test in JAWS by pressing Insert + F7 to open the Links List dialog, and in VoiceOver on Safari (macOS) by pressing VO + U to open the Rotor and navigating to Links. Flag any link whose label is ambiguous, duplicated with a different destination, or composed entirely of a URL string. \n
- Keyboard tab-through audit: Navigate the page using only the Tab key. Each time focus lands on a link, read only the focused element's visible text (or listen to the screen reader announcement). Without looking at surrounding content, decide whether the link's purpose is clear. Document every link where purpose is unclear from the link text alone. \n
- Image link check: Identify all links that contain only an image (no visible text). Inspect each with browser developer tools to verify the image has a non-empty, descriptive
altattribute, or the link has a descriptivearia-label. The accessible name computation should result in a meaningful phrase. \n - Duplicate link text check: Search the page's HTML for multiple instances of the same link text (for example, multiple "Read More" or "Buy Now" anchors). Verify whether these links point to the same destination (acceptable) or different destinations (a 2.4.9 failure unless disambiguated via
aria-labeloraria-labelledby). \n - Voice control test: Using Dragon NaturallySpeaking or Windows Voice Access, attempt to activate links by speaking their visible label. If the spoken label is ambiguous and multiple candidates appear (for example, speaking "Click Read More" highlights several links), this confirms a real-world usability failure aligned with 2.4.9. \n
How to Fix
\nGeneric "Read More" link text — Incorrect
\n<!-- Fails 2.4.9: link purpose cannot be determined from link text alone -->\n<article>\n <h3>How to Improve Your Website's Accessibility Score</h3>\n <p>Accessibility improvements can dramatically increase your user base...</p>\n <a href='/blog/improve-accessibility-score'>Read more</a>\n</article>\nGeneric "Read More" link text — Correct
\n<!-- Passes 2.4.9: link purpose is fully clear from link text alone -->\n<article>\n <h3>How to Improve Your Website's Accessibility Score</h3>\n <p>Accessibility improvements can dramatically increase your user base...</p>\n <a href='/blog/improve-accessibility-score'>\n Read more about improving your website's accessibility score\n </a>\n</article>\n\n<!-- Alternative: visually show short text but provide full accessible name -->\n<a href='/blog/improve-accessibility-score'\n aria-label='Read more about improving your website's accessibility score'>\n Read more\n</a>\n\nImage-only link with missing alt text — Incorrect
\n<!-- Fails 2.4.9: image link has no accessible name; screen readers announce URL or nothing -->\n<a href='https://accsible.com/pricing'>\n <img src='/icons/pricing.svg' alt=''>\n</a>\nImage-only link with missing alt text — Correct
\n<!-- Passes 2.4.9: alt text gives the link a fully descriptive accessible name -->\n<a href='https://accsible.com/pricing'>\n <img src='/icons/pricing.svg' alt='View Accsible pricing plans'>\n</a>\n\n<!-- Alternative using aria-label on the anchor -->\n<a href='https://accsible.com/pricing' aria-label='View Accsible pricing plans'>\n <img src='/icons/pricing.svg' alt=''>\n <!-- alt='' hides decorative image from AT; aria-label on <a> provides the name -->\n</a>\n\nMultiple identical "Satın Al" (Buy Now) links — Incorrect
\n<!-- Fails 2.4.9: three identical link labels pointing to different products -->\n<div class='product-card'>\n <h3>Temel Plan</h3>\n <a href='/plans/basic'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Profesyonel Plan</h3>\n <a href='/plans/pro'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Kurumsal Plan</h3>\n <a href='/plans/enterprise'>Satın Al</a>\n</div>\nMultiple identical "Satın Al" (Buy Now) links — Correct
\n<!-- Passes 2.4.9: each link has a unique, descriptive accessible name via aria-label -->\n<div class='product-card'>\n <h3>Temel Plan</h3>\n <a href='/plans/basic' aria-label='Temel Planı Satın Al'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Profesyonel Plan</h3>\n <a href='/plans/pro' aria-label='Profesyonel Planı Satın Al'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Kurumsal Plan</h3>\n <a href='/plans/enterprise' aria-label='Kurumsal Planı Satın Al'>Satın Al</a>\n</div>\n\n<!-- Alternative: use visually hidden text inside the anchor -->\n<a href='/plans/basic'>\n Satın Al <span class='sr-only'>— Temel Plan</span>\n</a>
(Content truncated due to token limit — please retry this article.)
