Internal links whose anchor text names no destination
What is this issue?
This is advice, not a defect. It reports internal links whose visible text says nothing about where the link goes — "click here", "read more", "this page", "more".
Anchor text is one of the very few descriptions of a page written by somebody other than that page's author. A search engine reads it as a summary of the destination; a person skimming a page reads the links before the prose around them; a screen reader can list every link on the page with nothing but its text. An anchor that says "here" gives all three of them nothing.
For a page to pass this check:
- Each of its internal links has anchor text that names, however briefly, what is at the other end.
Example: "To understand how we handle returns, click here." becomes "Read our returns policy." Same sentence, and now the link describes itself.
Two deliberate limits keep this honest:
- Only the whole anchor counts. "Read more about our refund policy" is descriptive and is not reported, even though it begins with a generic phrase.
- An anchor with no text at all is not reported. An empty link, or an image link with no alternative text, is a different problem with a different fix — there is no wording to improve.
Why it matters
- It is a description of the destination. Search engines use anchor text to understand what the linked page is about. A site whose internal links all say "read more" has declined to describe any of its own pages.
- People skim links. Readers scan a page for the link that looks like what they want. A column of identical "more" links forces them to read the surrounding sentence for every one.
- Assistive technology reads links out of context. A screen reader can present every link on a page as a list. "Click here, click here, click here" is that list on a page with three generic anchors, which is also why WCAG has a success criterion about it.
- It costs nothing to fix. The words are already being written; they just need to sit inside the anchor rather than beside it.
It is reported as a suggestion and carries no severity, so it never deducts from the health score. That is deliberate. "Click here" is worse writing than "our refund policy", but the page is not broken, the link works, and no measurable ranking or click-through cost can be pointed at for one anchor that says "read more". Advice is exactly what it is — the same line the catalogue draws for a title that would read better at 55 characters than at 47.
How to fix it
Move the description into the link. The words that describe the destination are usually already in the sentence, just outside the anchor. "To read our returns policy, click here" becomes "Read our returns policy".
Name the destination, briefly. Two to five words is plenty. The anchor should make sense read on its own, away from the sentence around it.
Fix the templates first. "Read more" on a card component appears once in the code and hundreds of times on the site. Where the card already shows a title, make the title the link.
Do not stuff keywords. Descriptive is the goal, not repetitive. Every link to one page using the same exact phrase reads as manipulation and helps nobody.
Vary naturally. Different pages linking to the same destination will describe it slightly differently, and that is healthy — it is more description of that page, not less.
Where the design needs a short affordance, keep the visible "Read more" but wrap the descriptive title in the link too, or add visually hidden text naming the destination.
Examples
Example 1: A link that describes itself
Scenario: Body copy pointing at a policy page.
Passes because: the anchor names the destination.
<p>Anything unopened can go back within 30 days — see our
<a href="/returns">returns policy</a>.</p>Example 2: The description left outside the anchor
Scenario: The same sentence, written the other way round.
Fails because: the anchor is "click here", which describes nothing.
<p>To read our returns policy, <a href="/returns">click here</a>.</p>Corrected version:
<p>Read our <a href="/returns">returns policy</a>.</p>Example 3: A card component with a shared affordance
Scenario: An article grid where every card ends in "Read more".
Fails because: every card contributes the same empty anchor, so the site describes none of its own articles.
<article>
<h3>How we handle returns</h3>
<a href="/returns">Read more</a>
</article>Corrected version: make the title the link, and keep the affordance as visually hidden context if the design needs it.
<article>
<h3><a href="/returns">How we handle returns</a></h3>
</article>Example 4: Not reported
Scenario: An anchor that starts with a generic phrase and then says where it goes.
Passes because: only the whole anchor is compared — this one names its destination.
<a href="/returns">Read more about our returns policy</a>How PixyScan detects this
Reads the visible text of every internal link. This is the text a reader would click, not the address it points at.
Reduces it to a comparable form. The text is lower-cased, runs of whitespace are collapsed, and decoration is trimmed off both ends — so
Read more »,READ MOREandread moreare all the same anchor. Punctuation inside the words is left alone, so "Editor's picks" is untouched.Compares the WHOLE anchor against a short list of phrases that name nothing. Whole-anchor, never a substring: "read more about our refund policy" names its destination and is not reported.
Keeps the list deliberately short. Words that are only sometimes empty — "download", "apply", "subscribe" — are not on it, because a check that cannot tell "Download" from "Download the annual report" should not be raising the question.
Skips anchors with no text. An empty link or an image link with no text is a different finding; there is no wording to rewrite.
Raises one suggestion per page, listing each generic anchor and the page it points at, so the sentence to rewrite can be found immediately.
The same rule drives the anchor-text explorer on the Links screen, so the column and the finding can never disagree about what counts as generic.
What we store
Storage Level
Page Level
Database Table / Prisma Model
PageInternalLink. The finding itself is stored on audit_issues.details.
Fields Used
| Field | Type | Description |
|---|---|---|
| page_internal_links.url_id | String | The page that carries the link, and the page this suggestion is raised against |
| page_internal_links.anchor_text | String | The visible text of the link — the field this check reads |
| page_internal_links.target_url_id | String | The page being linked to, so the suggestion can say where the empty anchor leads |
Stored Fields on the finding
| Field | Type | Description |
|---|---|---|
| genericAnchorCount | Int | How many of this page's internal links have anchor text that names nothing |
| anchors | Object[] | Up to 25 of them: the anchor text as written and the URL it points at |
| truncated | Boolean | Whether more exist than the finding lists |
| url | String | The page carrying the links |
Detection Dependencies
- Internal Links
- HTML Document — the visible text of each anchor