A link sends the user somewhere — but if it doesn't say where, it's a trap. A screen reader announces it as “link” and the user has no way to know whether to follow it. axe-core's link-name rule catches every anchor that's gone silent on you.
1. What is the link-name violation?
axe-core's link-name rule fires when an <a> (or any element with role="link") lacks an accessible name. The accessible name is the string a screen reader speaks when the link receives focus. Without one, the device announces only “link” and the user has no idea where it leads.
The rule maps to WCAG 2.1 2.4.4 Link Purpose (In Context) and 4.1.2 Name, Role, Value. Both are Level A — the lowest tier of conformance.
2. Why it matters
Most screen-reader users don't read pages top to bottom. They open the link list (NVDA: Ins+F7, JAWS: Ins+F7, VoiceOver: Ctrl+Opt+U). In that list links appear by name. Three “Read more,” five “Click here,” and four unnamed entries hand the user a useless menu.
An unnamed link is also invisible to keyboard focus. Tabbing into it, the user just hears “link” and can't make a decision about whether to follow.
3. When does it fire?
Five recurring patterns in production crawls:
- Empty link: Usually skip-links or in-page anchors that never got a name —
<a href="#main"></a>. - Icon-only link: Social icons, share glyphs, “more” arrows. The anchor contains an SVG and nothing else.
- Image-only link: An
<img>child with emptyalt— common in product cards on e-commerce. - Sole text hidden by aria-hidden: A designer hid label text to clean up the layout but never replaced it with an alternative.
- Decorative-by-mistake:
aria-hidden="true"on a focusable link creates a “focusable but invisible” conflict — focus lands but the user hears nothing.
4. The fixes
4.1 Social-icon links
The footer Twitter/Instagram/LinkedIn row gets it wrong on nearly every site: an SVG with no text, so the screen reader plays “link, link, link.” Either label the anchor or include a visually hidden span.
<a href="https://twitter.com/keysonar">
<svg viewBox="0 0 24 24">...</svg>
</a><a
href="https://twitter.com/keysonar"
aria-label="Follow us on Twitter"
>
<svg aria-hidden="true" viewBox="0 0 24 24">...</svg>
</a>4.2 Card link with image and caption
A product card usually wraps both an image and a caption inside a single anchor. Set the image alt to empty — the caption already supplies the accessible name, so the duplicate would force the screen reader to read the title twice.
<a href="/p/123">
<img src="/p/123.jpg" alt="iPhone 15 Pro 256GB">
<h3>iPhone 15 Pro 256GB</h3>
<p>$1,299</p>
</a><a href="/p/123">
<img src="/p/123.jpg" alt="">
<h3>iPhone 15 Pro 256GB</h3>
<p>$1,299</p>
</a>4.3 "Read more" / "Learn more" links
Repeating the same anchor text down a list ("Read more" under every article) passes link-name technically but breaks WCAG 2.4.4's contextual purpose requirement. Two standard fixes:
<a
href="/blog/seo-fundamentals"
aria-label="Read more about SEO fundamentals"
>
Read more
<span aria-hidden="true"> →</span>
</a><article>
<h2 id="post-101">SEO fundamentals</h2>
<p>...</p>
<a href="/blog/seo-fundamentals" aria-labelledby="post-101">
Read more
</a>
</article>4.4 Skip-link / in-page anchors
The non-negotiable “skip to main content” link is hidden visually but must carry text in the accessibility tree. Reveal it on focus.
<a href="#main" class="skip-link">
Skip to main content
</a>
<style>
.skip-link {
position: absolute;
left: -9999px;
top: auto;
}
.skip-link:focus {
left: 1rem;
top: 1rem;
z-index: 999;
background: #000;
color: #fff;
padding: 0.5rem 1rem;
}
</style>4.5 React / Next.js links
<Link href="/cart">
<ShoppingCart className="w-5 h-5" />
</Link><Link href="/cart" aria-label={t("nav.cart")}>
<ShoppingCart aria-hidden className="w-5 h-5" />
</Link>On a multi-language site, source aria-label from the active locale's dictionary. A hard-coded English "Cart" on a Turkish page is rendered by an English speech engine and becomes meaningless to the user.
5. How the accessible name is computed
The browser walks this priority list and uses the first non-empty result:
aria-labelledbyaria-label- The link's own text content (text, img alt, etc.)
titleattribute — last resort
<a href="/account" aria-label="Profile">
My account
</a><a href="/account">My account</a>6. Cases that get missed
- Fake links:
href="#"orjavascript:void(0)on elements that should be buttons. Convert them to<button>— and they still need a name. - Many same-named links on the same page: Ten "Details" in a row leave the screen-reader user no way to tell them apart. Add per-row context via aria-label.
- Buttons nested inside links:
<a><button>...</button></a>is invalid HTML and ambiguous to assistive tech. axe-core usually catches this; resolve it at design time. - Links that open a new tab:
target="_blank"alone isn't enough — say so:aria-label="… (opens in a new tab)”. - title attribute: Invisible on touch and inconsistent across screen readers. Don't rely on it for the accessible name.
7. How to test
- Screen-reader link list: NVDA Ins+F7, VoiceOver Ctrl+Opt+U. If the list contains "link," "click," or duplicate names, you have work to do.
- axe DevTools: Browser extension, instant per-page scan. Best for tight-loop development.
- Keysonar SEO Tools: Site-wide automated crawl, every page with a link-name violation listed, regression tracking across releases. No DevTools needed.
- Keyboard-only test: Drop the mouse and tab through the page. If you ever land on a link and can't tell what it does, it's missing a name.
8. Quick checklist
- Every <a> has visible text, an aria-label, or aria-labelledby.
- Icon-only links carry an aria-label in the same language as the page.
- Links wrapping <img> either have a non-empty alt OR adjacent text (alt empty when text exists).
- Repeating 'Read more' links are disambiguated via aria-label/aria-labelledby.
- A skip-link exists at the top of every page and becomes visible on focus.
- Links that open a new tab announce that fact.
- No redundant aria-label on links that already have visible text.
- Fake (#, javascript:void(0)) links are converted to real buttons.
9. References
- WCAG 2.1 SC 2.4.4 — Link Purpose (In Context) — Level A
- WCAG 2.1 SC 4.1.2 — Name, Role, Value — Level A
- WCAG 2.1 SC 2.4.9 — Link Purpose (Link Only) — Level AAA
- HTML Living Standard — The a element
- WAI-ARIA Authoring Practices: Link pattern