About seo-images-media
seo-images-media is an SEO audit skill for assessing image descriptions, dimensions, formats, and embedded video metadata. It helps teams identify accessibility and media markup issues, with proposed alt text and fixes limited to what page context supports.
Key features
- 01Check image alt presence and quality
- 02Flag missing image dimensions
- 03Review legacy image formats
- 04Detect videos without VideoObject schema
- 05Propose contextual alt text
Use cases
- 01Find content images missing alt text
- 02Identify images without reserved dimensions
- 03Audit embedded video structured data
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ hainrixz/ claude-seo-ai --skill seo-images-mediaAfter installing, type/seo-images-mediain Claude Code to confirm it loaded.
Details
From the project READMEseo-images-media (M9)
Accessible, well-described media is read by both ranking systems and AI extractors — alt text is the primary semantic handle for an image. Reference: references/schema-tier1.md (VideoObject row).
Inputs
Work from the PageSnapshot named in your dispatch envelope: read parsed from <run_dir>/pages/<slug>.json (images[] with alt_present/sized/lazy, iframes, jsonld[]); Grep pages/<slug>.html for verbatim evidence; site artifacts live in <run_dir>/site/{robots.json,sitemaps.json,discovery.json}. Deterministic findings already emitted by audit.mjs are listed in <run_dir>/findings.deterministic.json — do not re-emit those ids; add model-judged findings only. If invoked directly with a URL/path and no snapshot exists, first run node "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.mjs" <target> --out "${CLAUDE_PLUGIN_DATA}/runs" and use the printed snapshot path.
Audits
Working from the PageSnapshot (parsed_rendered when render.used is not none, else parsed):
- Alt presence: every content
<img>has analtattribute. Distinguish decorative images (alt=""+role="presentation"is correct, not a finding) from missingaltentirely (fail). - Alt quality: not empty on a content image; not the filename (
IMG_2031.jpg); not duplicated verbatim across distinct images; not keyword-stuffed (comma-separated keyword lists are an anti-pattern). Alt should be descriptive and contextual to surrounding content. Target length ~80-140 chars — long enough to be specific, short enough that screen readers/AI don't truncate. - Dimensions:
widthandheightset on<img>(or aspect-ratio reserved in CSS) to prevent layout shift (CLS, a Core Web Vitals input — defer the CWV measurement itself to the perf module). - Format: flag legacy
jpg/pngwhere a modern format (WebP/AVIF) or a responsive<picture>/srcsetwould serve smaller bytes. - Video: embedded video (
<video>, YouTube/Vimeo iframe) withoutVideoObjectJSON-LD — coordinate with M5; required/recommended props inreferences/schema-tier1.md.
Fixes
- AUTO (
fixable: auto): addwidth/heightto<img>from the source asset's intrinsic dimensions (deterministic, additive, verifiable) — emitted as a diff forfix. - PROPOSED (
fixable: proposed): generate contextual alt text inferred from the image plus its surrounding heading/caption/paragraph. Drafts require per-item human accept (alt is editorial). Never fabricate what an image depicts beyond what the page context supports — leave a clearly-markedTODO: describe imageplaceholder when context is insufficient, or ask the user. - ADVISORY (
fixable: advisory): format upgrades (WebP/AVIF,srcset). The tool cannot transcode binaries, so it never writes these — it recommends only.
Verification
- Method
dom_assert: re-parse the snapshot and assert the condition (alt non-empty,width+heightpresent, not a filename, etc.). - When dimension checks need the intrinsic size of a remote asset and no fetch tier is available, status is
needs_api, never a falsepass.
Findings
Emit findings per schema/finding.schema.json; axis both; severity 3 across the module. Severity policy: 5 is reserved for catastrophic, eligibility-killing facts at site/template scope; 4 major · 3 moderate · 2 minor · 1 cosmetic · 0 informational — and only an established severity-5 fail in an active category can cap a score (references/scoring-model.md). Nothing in M9 reaches 4.
M9.alt.missing— content<img>with noaltattribute. statusfail,fixable: proposed, confidenceestablished.evidence.observedquotes the offending<img>tag.M9.img.no_dimensions—<img>lackingwidth/height. statuswarn,fixable: auto, confidencedirectional(CLS link).M9.video.missing_videoobject— embedded video without VideoObject schema. statuswarn,fixable: proposed, confidenceestablished. Each finding:evidence.observedquotes the page;verification.reproduceis runnable, e.g.node "${CLAUDE_PLUGIN_ROOT}/scripts/parse-html.mjs" --snapshot <pages/<slug>.json>(or--url <u>) then inspect theimagesblock (missing_alt,empty_alt,missing_dimensions).expected_impactis banded + confidence-tagged (no naked %).
Honesty
- Alt text aids accessibility and image/AI understanding; treat ranking lift as
directional, not a guaranteed gain — do not promise traffic from alt rewrites. - Keyword-stuffing alt is harmful, not helpful — flag it, never generate it.
- WebP/AVIF reduce bytes (a real perf input) but format alone is not a documented ranking factor; keep it
advisory/lowmagnitude.