Lighthouse audit link-name · Accessibility

Links do not have a discernible name: how to fix it

View raw .md for LLMs / your notes
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

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:

  1. aria-labelledby pointing at another element
  2. aria-label on the anchor
  3. The text content of the anchor, including alt text of any image inside it
  4. title on 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".

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:

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:

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:

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.

How do I verify the fix?

  1. Re-run Lighthouse. The link-name audit should pass and move into "Passed audits".
  2. 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.
  3. 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.
  4. Add axe DevTools or eslint-plugin-jsx-a11y to catch regressions before they ship.

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.

Run audit →
Add us as a preferred source on Google

One click, and Google shows more of lighthouse-md.com in your search results.