Quick answer: This audit fails when a link has no text a screen reader can announce, usually an icon-only link such as a cart or social icon. Fix it by adding an aria-label to the anchor, adding visually hidden text inside it, or giving an image inside the link real alt text.
This Lighthouse audit fails when a link on the page has no text a screen reader can announce. The most common cause is an icon-only link: a magnifying glass, a cart, a social icon, a logo wrapped in an anchor. Sighted users see the icon. A screen reader reaches the link and says "link", or reads out the URL, which tells the user nothing about where it goes.
TL;DR
- What: One or more
<a>elements have no accessible name. - Why it matters: Screen readers announce these links as "link" or read the raw URL, so the user cannot tell what they do.
- Fix: Give every link real text, or an
aria-label, or visually hidden text. Never leave an anchor with only an icon inside it.
What does the link-name audit check?
Lighthouse runs the axe-core rule link-name against the rendered DOM. It computes the accessible name of each <a> element that has an href, and fails the audit if that name is empty.
The accessible name comes from the first of these that produces text:
aria-labelledbypointing at another elementaria-labelon the anchor- The text content of the anchor, including
alttext of any image inside it titleon the anchor
If all four are empty, the link has no discernible name and the audit fails. The passing title reads "Links have a discernible name"; the failing one is "Links do not have a discernible name".
Why do links without a discernible name matter?
Screen reader users navigate by pulling up a list of every link on the page, out of context. That list is built entirely from accessible names. A nameless link shows up as "link", or as https://example.com/cart?ref=header, alongside a dozen others that look the same.
It also affects:
- Voice control. Users say "click Search" to activate a link. With no name there is nothing to say.
- WCAG conformance. This is a failure of SC 2.4.4 Link Purpose (In Context) at Level A, and it is one of the most common failures on the web.
- SEO, indirectly. Search engines use anchor text as a relevance signal. An empty link passes none.
How do I fix "links do not have a discernible name"?
Pick whichever of these fits the markup. All four produce a valid accessible name.
<!-- FAILS: icon-only link, nothing to announce -->
<a href="/cart"><svg>...</svg></a>
<!-- FIX 1: aria-label on the anchor. Best for icon-only links. -->
<a href="/cart" aria-label="Shopping cart"><svg aria-hidden="true">...</svg></a>
<!-- FIX 2: visually hidden text. Works without ARIA and survives translation. -->
<a href="/cart">
<svg aria-hidden="true">...</svg>
<span class="sr-only">Shopping cart</span>
</a>
<!-- FIX 3: alt text, when the link wraps an <img> -->
<a href="/"><img src="/logo.svg" alt="Acme home"></a>
<!-- FIX 4: real visible text, always the best option when you have room -->
<a href="/cart">Cart</a>
The sr-only class, if your CSS framework does not already ship one:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
Note the aria-hidden="true" on the icon in fixes 1 and 2. Without it, some screen readers announce the SVG's own title alongside your label, producing "Shopping cart, cart icon". Hide the decorative graphic and let the label speak.
What are the most common causes on a real site?
In a scan of 269 production storefronts, link-name failed on 67.3% of them. The offenders were almost always the same handful of patterns:
- Social icons in the footer. A row of anchors containing only an SVG each.
- The logo link.
<a href="/"><img src="logo.svg" alt=""></a>with an emptyalt, which is correct for a decorative image but leaves the link nameless. - Icon buttons that are really links. Search, cart, account, hamburger menu.
- Pagination. Arrows rendered as
‹and›characters, or as icons, with no label. - "Read more" cards where the whole card is an anchor wrapping an image with empty
altand the heading sits outside the link. - Empty tracking anchors.
<a href="#" onclick="track()"></a>with no content at all.
How do I fix this in React, Next.js, WordPress, or Shopify?
React / Next.js
Icon components usually spread props, so the label goes on the Link, not the icon:
// FAILS
<Link href="/cart"><CartIcon /></Link>
// FIXED
<Link href="/cart" aria-label="Shopping cart">
<CartIcon aria-hidden="true" />
</Link>
If you use next/image inside a link, an empty alt leaves the link nameless. Either give the image real alt text describing the destination, or add aria-label to the Link.
Catch these in CI with eslint-plugin-jsx-a11y, which ships an anchor-has-content rule for exactly this.
WordPress
Most themes generate the social and logo markup for you. Check:
- Site logo block. Set the site title so the logo link inherits a name, or add alt text to the logo in the Customizer.
- Social Icons block. WordPress core adds labels automatically, but many page builders do not. Inspect the rendered anchor.
- Menu items with icon fonts. If the menu label is hidden via CSS, replace
display: nonewith the.sr-onlypattern above.display: noneremoves the text from the accessibility tree; clipping keeps it.
Shopify
The usual culprits are in header.liquid and footer.liquid:
<!-- FAILS -->
<a href="{{ routes.cart_url }}">{% render 'icon-cart' %}</a>
<!-- FIXED -->
<a href="{{ routes.cart_url }}" aria-label="{{ 'layout.cart.title' | t }}">
{% render 'icon-cart' %}
</a>
Use a translation key rather than a hardcoded string so the label follows the storefront locale. Dawn-based themes already do this; older and heavily customised themes frequently do not.
What link-name pitfalls should I avoid?
- Do not use
titleas your fix. It technically satisfies the audit, buttitleis not shown on touch devices, is inconsistently announced, and is invisible to voice control users. It passes the test without helping anyone. - Do not use
display: noneorvisibility: hiddento hide link text. Both remove the text from the accessibility tree, so the link goes back to having no name. Use the clipping.sr-onlypattern. - Do not label every link "click here" or "read more". That passes
link-nameand fails SC 2.4.9, and it is what the separatelink-textaudit checks. Name the destination. - Do not put
aria-hidden="true"on the anchor itself. It hides the link from assistive tech entirely while leaving it keyboard focusable, which is worse than the original problem. - Do not rely on an empty
altinside the link.alt=""is correct for decoration, but if that image is the only content of the anchor, the link is nameless. - Watch for duplicate names. Ten links all labelled "Read more" pass this audit but produce a useless link list. Include the destination: "Read more about shipping".
How do I verify the fix?
- Re-run Lighthouse. The
link-nameaudit should pass and move into "Passed audits". - In Chrome DevTools, select the anchor and check the Accessibility pane. The Computed Properties → Name field shows exactly what a screen reader will announce. Empty means it still fails.
- Test with a real screen reader's link list: VoiceOver on Mac (VO+U, then arrow to Links), or NVDA on Windows (Insert+F7). Read the list without looking at the page. If you cannot tell where a link goes, the name is not good enough.
- Add axe DevTools or
eslint-plugin-jsx-a11yto catch regressions before they ship.
Related audits
- Image alt attributes, the images inside those links
- Document main landmark, landmark navigation
- Heading order, semantic structure
- Color contrast, visual accessibility
Audit your URL at https://lighthouse-md.com.
Audit your page now
Paste your URL, get scores plus a CLAUDE.md plan for Claude Code.