Internal links with empty anchor text
What is this issue?
The page has links to other pages of your site that contain no words at all.
Anchor text — the visible text of a link — is how a search engine learns what the page at the other end is about. A link with no text tells it nothing. Common causes:
- an icon link with no label:
<a href="/cart"><i class="icon-cart"></i></a> - a logo or button drawn with an inline SVG that has no
<title> - an empty link left behind by a template:
<a href="/about"></a>
For a page to pass this check, every internal link has one of:
- visible text;
- an accessible name: a non-blank
aria-label, anaria-labelledbypointing at an element that has text, or an inline<svg>with a non-blank<title>; - or is an image link — those are judged by the image-link check (#199) against their alt text.
An accessible name counts. A cart icon with aria-label="Shopping cart" or a
logo SVG with a <title> is named, just not in words on screen. Counting it keeps
the icon links of a site-wide header and footer from being reported on every page.
The title attribute does not count. It is a tooltip shown on hover, not a
name, and a link whose only description is a tooltip is still a link with nothing
to read.
Why it matters
Anchor text is a description of the destination. Each internal link is your own site telling search engines what the linked page is about. An empty link spends the link and says nothing.
Repeated empty links waste your strongest links. Icon links usually sit in the header and footer, so they appear on every page. Those sitewide links are the ones search engines see most often.
Readers who cannot see the icon get nothing. Without text, a screen reader announces "link" and the address, or nothing useful at all — unless an
aria-labelfills the gap.AI answer engines read anchor text too. When an assistant summarises your site's structure, the words on your links are part of what it reads.
Effect on the health score
This is a standard-severity issue in the Link Integrity lens, raised once per page however many empty links the page carries.
How to fix it
Add words to the link. If the design has no room for visible text, hide it visually but keep it in the HTML:
<!-- Before --> <a href="/cart"><i class="icon-cart"></i></a> <!-- After: visible to search engines and screen readers, not on screen --> <a href="/cart"><i class="icon-cart" aria-hidden="true"></i> <span class="visually-hidden">Shopping cart</span></a>.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }Give an inline SVG a title.
<a href="/"><svg role="img"><title>Example Co home</title>…</svg></a>Or use an image with alt text.
<a href="/"><img src="/logo.svg" alt="Example Co home"></a>is an image link and is judged by its alt.Remove empty leftovers. An
<a href="/about"></a>with nothing inside does nothing for anyone — delete it.Fix it once, in the template. When every page reports the same targets, the link is in the header or footer.
Examples
Example 1: A text link
Passes because: the link says where it goes.
<a href="/pricing">See our plans</a>Example 2: An icon-font link
Fails because: the <i> has no text, so the link has none.
<a href="/account"><i class="fa fa-user"></i></a>Corrected version:
<a href="/account"><i class="fa fa-user" aria-hidden="true"></i>
<span class="visually-hidden">Your account</span></a>Example 3: Icon links with an accessible name
Passes because: each link is named — by aria-label, by aria-labelledby
pointing at text, or by the SVG's <title> — even though no words show on screen.
<a href="/cart" aria-label="Shopping cart"><i class="icon-cart"></i></a>
<span id="acct-label" hidden>Your account</span>
<a href="/account" aria-labelledby="acct-label"><svg>…</svg></a>
<a href="/"><svg role="img"><title>Example Co home</title><path d="…"/></svg></a>Example 4: An icon link named only by a tooltip
Fails because: the title attribute is a hover hint, not a name.
<a href="/" title="Home"><svg viewBox="0 0 24 24"><path d="…"/></svg></a>Corrected version:
<a href="/" aria-label="Home"><svg viewBox="0 0 24 24"><path d="…"/></svg></a>Example 5: An image link
Not reported here. A link whose content is an image is judged on its alt text by the image-link check (#199).
<a href="/"><img src="/logo.png" alt="Example Co home"></a>How PixyScan detects this
Reads every link to another page of the same site (the same host as the page) from the HTML the server sent.
Classifies each link by what it is made of:
- text — it has visible text (whitespace and
do not count; text inside nested elements and an SVG<title>do); - image — no text, but at least one
<img>. These belong to #199; - empty — neither.
- text — it has visible text (whitespace and
Accepts an accessible name in place of text. An empty link is not reported when it has any of:
- a non-blank
aria-label; - an
aria-labelledbynaming at least one element on the page that has text; - an inline
<svg>containing a non-blank<title>.
The
titleattribute is not accepted: it is a tooltip, not a name.- a non-blank
Reports the rest. This changes only what is reported. The anchor text stored for the link is still its visible text (or an image's alt), so a link named only by
aria-labelis listed with no anchor text in the Links report.Ignores links to other domains, fragment-only links (
href="#top"), and links that are not links at all (javascript:, see #197).Counts every anchor, including links to pages that robots.txt or your exclude rules keep out of the crawl — an empty link is a fault in the markup whether or not the target was crawled.
Raises one finding per page with the number of empty links and up to five of the distinct pages they point at.
What we store
Storage Level
Page Level
Database Table / Prisma Model
audit_issues.details
Decided from the page's own links while it is crawled. The link rows themselves
(internal_links) are unchanged: their anchor_text is null for both an empty
link and an image link without alt, and this finding is what tells the two apart.
Stored Fields
| Field | Type | Description |
|---|---|---|
| message | String | "Found N internal link(s) with no anchor text" |
| emptyAnchorLinkCount | Int | Empty internal links on the page, counted per anchor |
| samples | String[] | Up to five distinct target URLs of those links |
| truncated | Boolean | True when more than five distinct targets were affected |
Detection Dependencies
- HTML Document — every internal
<a href>, its text and whether it contains an image