Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.

Fix empty and broken links

All links contain accessible text content and do not lead to broken destinations.

Utilities
Quick take
Typical fix time 15 min
  • Every link must have accessible text (visible or via aria-label)
  • Icon-only links need aria-label describing the destination
  • Empty anchor tags are completely inaccessible—always add content
  • Use visually-hidden text when visual labels aren't desired
Why it matters: Screen readers announce empty links as just 'link' with no context—users have no idea where they lead or what they do, making navigation impossible.

Rule Details

Every link must have an accessible name that describes its destination or purpose.

Code Example

<!-- ❌ Bad: Completely empty link -->
<a href="/home"></a>
<!-- Screen reader: "link" (no context) -->
 
<!-- ❌ Bad: Image link with no alt -->
<a href="/profile">
  <img src="avatar.jpg">
</a>
<!-- Screen reader: "link, image" (no context) -->
 
<!-- ❌ Bad: Icon link with no label -->
<a href="/settings">
  <svg>...</svg>
</a>
<!-- Screen reader: "link" (no context) -->

Why It Matters

Screen readers announce empty links as just 'link' with no context—users have no idea where they lead or what they do, making navigation impossible.

Add Visible Text

<!-- ✅ Good: Visible link text -->
<a href="/home">Go to homepage</a>
 
<!-- ✅ Good: Image with descriptive alt -->
<a href="/profile">
  <img src="avatar.jpg" alt="View your profile">
</a>
<!-- ✅ Good: Icon link with aria-label -->
<a href="/settings" aria-label="Account settings">
  <svg aria-hidden="true">...</svg>
</a>
 
<!-- ✅ Good: Social media icons -->
<a href="https://twitter.com/company" aria-label="Follow us on Twitter">
  <svg aria-hidden="true"><!-- Twitter icon --></svg>
</a>

Visually Hidden Text

<!-- ✅ Good: Visually hidden but screen reader accessible -->
<a href="/cart">
  <svg aria-hidden="true"><!-- Cart icon --></svg>
  <span class="sr-only">Shopping cart (3 items)</span>
</a>
.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;
}

React Component

interface IconLinkProps {
  href: string
  label: string
  icon: React.ReactNode
  isExternal?: boolean
}
 
function IconLink({ href, label, icon, isExternal }: IconLinkProps) {
  return (
    <a
      href={href}
      aria-label={label}
      target={isExternal ? '_blank' : undefined}
      rel={isExternal ? 'noopener noreferrer' : undefined}
    >
      <span aria-hidden="true">{icon}</span>
      {isExternal && <span className="sr-only">(opens in new tab)</span>}
    </a>
  )
}
 
// Usage
<IconLink
  href="/settings"
  label="Account settings"
  icon={<SettingsIcon />}
/>
// Browser console check
document.querySelectorAll('a').forEach(link => {
  const text = link.textContent?.trim()
  const ariaLabel = link.getAttribute('aria-label')
  const imgAlt = link.querySelector('img')?.getAttribute('alt')
 
  if (!text && !ariaLabel && !imgAlt) {
    console.warn('Empty link found:', link)
  }
})

Exceptions

  • Evaluate the rendered experience before treating a static-code smell as a blocker; interaction timing, browser behavior, and assistive technology output often determine severity.
  • Not every secondary accessibility issue deserves equal weight; prioritize the issue that most directly blocks perception, operation, or understanding.
  • Avoid adding redundant markup or ARIA solely to satisfy a rule when a simpler semantic implementation would eliminate the issue entirely.

Verification

Automated Checks

  • Use axe DevTools or Lighthouse to find empty links

Manual Checks

  • Navigate with screen reader—every link should announce its purpose
  • Check that image links have alt text or aria-label
  • Verify icon-only links have accessible names

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Scan for links with no text content (empty anchor tags, icon-only links without labels). Verify all links have accessible names via text content, aria-label, or aria-labelledby. Check for broken link destinations.

Fix

Auto-fix issues

Add descriptive text to empty links. For icon-only links, add aria-label describing the destination. Use visually-hidden text if visible labels are not desired. Remove or fix broken links.

Explain

Learn more

Explain how screen readers announce empty links as just 'link' with no context, leaving users unable to understand where the link leads or what action it performs.

Review

Code review

Review the rendered markup and interactive states that affect Fix empty and broken links. Flag exact elements, roles, labels, focus behavior, or keyboard interactions that violate the rule, and note how to verify the fix with browser accessibility tooling or assistive tech.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

axe DevTools
deque.comTool

Rules that often go hand-in-hand with this one.

Use descriptive link text

Link text clearly describes the destination or purpose without relying on surrounding context.

Accessibility
Provide accessible names for tree items

All elements with role="treeitem" must have a descriptive accessible name so screen reader users can navigate hierarchical tree widgets.

Accessibility
Avoid sensory-only instructions

Instructions do not rely solely on sensory characteristics like color, shape, size, location, or sound.

Accessibility
Provide accessible names for ARIA command elements

Checks that command elements like buttons and links have accessible names for screen reader support.

Accessibility

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385