Images have alt text
Why it matters
Screen readers announce an image with no alt attribute by reading the filename or the word "graphic" — a photo of your CEO becomes "IMG_4782.jpg" and a chart becomes "unlabeled graphic." Missing alt text is direct plaintiff's-bar lawsuit bait: Domino's v. Robles (2019 SCOTUS denied cert) and Gil v. Winn-Dixie ($250K plus $4M in ordered remediation) both turned on content-image accessibility, and Seyfarth Shaw tracks roughly 3,600 federal ADA website lawsuits filed annually with about 75% citing missing alt text as a primary claim. Users relying on assistive tech lose the information the image was carrying, which on transactional pages (product photos, verification checks, captcha alternatives) blocks task completion entirely. AI coding tools are particularly prone to this failure because next/image and <img> render without alt (it is an optional prop, not a required one), and generated React components routinely ship with the attribute absent. This check also catches the opposite failure: a codebase where every image carries alt="", meaning the model defaulted everything to decorative rather than writing real descriptions. Missing alt text is a documented WCAG 2.2 Level A failure (SC 1.1.1) and the single most common complaint captured in accessibility support tickets.
Severity rationale
Critical because missing `alt` on content images is the #1 claim in ~3,600 annual federal ADA website lawsuits tracked by Seyfarth Shaw — the exposure is an active, industrialized plaintiff's bar, not a theoretical risk.
Remediation
Add alt to every <img> / <Image>. For decorative images, use alt="". For content images, describe the content concisely:
<Image src="/team/jane.jpg" alt="Jane Smith, CTO" width={120} height={120} />
Deeper remediation guidance and cross-reference coverage for this check lives in the accessibility-fundamentals Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.
Detection
- ID:
images-have-alt-text - Severity:
critical - What to look for: Enumerate every
<img>JSX element and<Image>fromnext/image. For each, check whether thealtattribute is present (any value, including""for decorative). Also check raw HTML in.htmlfiles, MDX, anddangerouslySetInnerHTMLblocks. Flag any image with a dynamic src (src={user.avatar},{post.hero}) whose alt is missing or bound to a nullable expression without a??fallback — those renderalt=""when undefined. - Pass criteria: ≥99% of image elements have the
altattribute present. AT LEAST ONE image has a non-empty alt — if 100% usealt="", that auto-fails (everything-decorative is never accurate on a real app). - Fail criteria: >1% missing the attribute, OR every image uses
alt="", OR any dynamic-source image has no alt binding / has a nullable-bound alt without fallback.// TODO: add alt textdoes not count. - Skip (N/A) when: No JSX/HTML images (pure API / CLI / library / backend). Quote:
"0 image elements across N source files scanned". - Report even on pass:
"N images across M files: P with non-empty alt, Q with empty (decorative), R missing. Coverage (P+Q)/N = X%. Example descriptive alt: {one}". - Detail on fail:
"12 of 80 images missing alt (15% — should be ≤1%). app/page.tsx:34, components/hero.tsx:12 (<Image src={product.image} />, dynamic, no alt binding), app/about/page.tsx:48". - Cross-reference: For keyboard nav, ARIA, contrast, focus management, run
accessibility-fundamentalsthenaccessibility-wcag. - Remediation:
Decorative:<Image src="/team/jane.jpg" alt="Jane Smith, CTO" width={120} height={120} />alt="". Content images: describe the content concisely.
Taxons
History
- 2026-04-22·v1.0.0·Initial import from project-snapshot via Phase 8.1 bundling·by phase-8-1-bundle-project-snapshot
- 2026-04-22·v2.0.0·Phase 9 consequence-first restructure — moved to new section slug, added news/incident references, severity reviewed.·by phase-9-stack-scan-v3
- 2026-04-23·v2.1.0·Phase 9.1 tighten — coverage threshold ratcheted 95% → 99%; all-empty-alt pattern auto-fails; dynamic-source images with no alt binding auto-fail; detail must name file path and percentage.·by phase-9-1-stack-scan-v3-1
- 2026-04-25·v2.1.1·v3.1.0 pre-ship trim — prose compression for under-80K MCP cap; merged overlapping Fail-criteria / Do-NOT-pass-when sections; compressed enumeration prose; one remediation example per pattern. No semantic change; anti-sycophancy guards preserved.·by phase-9-1-stack-scan-v3-1