Skip to main content
interlace
Plugin: react-a11yRules

alt-text

Enforce alt text on images and other visual elements that carry accessibility impact.

WCAG: 1.1.1 Non-text Content (Level A)

Enforce alt text on images and other visual elements that carry accessibility impact. Missing alt text breaks screen readers, blocks Lighthouse a11y audits, and fails WCAG 1.1.1 (Level A).

This rule is part of eslint-plugin-react-a11y.

Quick Summary

AspectDetails
SeverityCritical (Accessibility — WCAG Level A)
Auto-Fix💡 Suggestions (placeholder alt, role="presentation"alt="")
CategoryReact Accessibility
WCAG1.1.1 Non-text Content (Level A)
Best ForAny React application; mandatory for sites with WCAG conformance

What the rule checks

The rule covers every element that conveys non-text content to sighted users:

ElementRequiredEmpty alt="" allowed?
<img>alt, or role="presentation" paired with alt=""Yes — only for decorative images
<area> (image map)alt describing the link targetNo
<input type="image">alt or aria-label describing the actionNo
<object>Inner text, aria-label, aria-labelledby, or titlen/a — alt isn't valid on <object>

Examples

❌ Incorrect

<img src="hero.jpg" />                     // missing alt
<img src="hero.jpg" alt="" />              // empty alt without role="presentation"
<img src="hero.jpg" role="presentation" /> // role without alt=""
<input type="image" src="submit.png" />    // no accessible name
<area shape="rect" coords="0,0,82,126" href="/products" />  // missing alt
<object data="diagram.svg" />              // no text alternative

✅ Correct

<img src="hero.jpg" alt="Customer service agent helping a user" />
<img src="divider.svg" alt="" role="presentation" />        // decorative
<img src="logo.svg" alt="Acme Corp" />
<input type="image" src="submit.png" alt="Submit form" />
<area shape="rect" coords="0,0,82,126" href="/products" alt="View product catalog" />
<object data="diagram.svg" aria-label="System architecture diagram">
  System architecture diagram (fallback text)
</object>

Error Message Format

♿ REACT-A11Y CWE-252 | Image missing alt text | CRITICAL
   Fix: Add a descriptive `alt` attribute, or mark the image decorative with `role="presentation"` and `alt=""`.

Known False Negatives

  • Image-like usage via background CSS (<div style={{ backgroundImage }} />) is not flagged — CSS-painted images are outside the rule's scope and should use an explicit <img> when they carry meaning.
  • Dynamically composed alt text (e.g. alt={maybeUndefined}) is accepted; the rule cannot prove the runtime value will not be empty. Pair with TypeScript narrowing to make the alt prop required at the type level.
  • Custom image wrappers that re-export <img> via a generic prop spread are tracked only when the component name follows the Image/Img/Picture heuristic.

Not a finding

The image component is resolved from its import, so a same-named component from an unrelated package is out of scope.

CodeWhy it is silent
import Image from 'next/image';
<Image src={s} alt="hero" />
It has alt text.
import Image from 'some-chart-lib';
<Image src={s} />
Not an image component — the module is what counts, not the name.
<img src={s} alt="" />An explicitly empty alt marks the image decorative, which is the correct annotation.
<img src={s} alt={caption} />A dynamic alt is trusted, per the standard jsx-a11y/alt-text contract.

Two things put a component in scope: a default import from next/image, next/legacy/image or next/future/image, and any name listed in the imgComponents option. The import path covers the default configuration; imgComponents is how you add your own wrapper. A NAMED import is not enough — next/image also exports getImageProps, a helper that returns props rather than rendering.

If it fires on next/image, next/legacy/image or next/future/image, that is deliberate: it is the dominant image component in every Next.js app and was previously invisible unless you set { img: ['Image'] } — a default nobody sets, on the framework most likely to need it.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.