← /how-to/

How to add alt text to every WordPress image with AI

Thousands of empty alt fields, one reviewed pass: your AI drafts every description in local files, you review each diff, and only approved text ships. Try it now free → or book a demo with Curtis

The media library counter says 4,800 images. The audit says most of their alt fields are empty, and you believe it without checking, because you know how it happened. Alt text is a field on the upload screen that nothing enforces. Skip it and the image still renders, the post still publishes, the page looks identical. So it got skipped, on every upload day, by every contributor, for years, and going back was never anyone's job. The bill arrives somewhere you cannot see: a screen reader hitting one of those images typically falls back to reading the filename, hero-banner-final-v3.jpg, aloud.

Writing 4,800 descriptions is not a typing problem, it is judgment at library scale. Describe what matters in the context of the post the image sits in, mark the decorative ones with an empty alt instead of describing them, keep keywords where they are honest. That is work an AI agent is genuinely good at, and exactly the work you should not let one publish unread, because a wrong description misleads a screen reader user in a way an empty field does not. The fix is a loop: the posts and the library as local files, the agent drafting against your rules, your eyes on every diff, and nothing shipping unapproved.

Your options

The media library, by hand

Open each image's attachment details and type a description. The arrow keys step you from image to image without closing the panel, which is the fastest pure-manual path, and list-view and spreadsheet-style editors can bulk-edit the library field. Hand-writing has the one property every automated route lacks: a person looks at the actual photo. Two problems. Scale is the obvious one; 4,800 images is weeks of work that loses to any deadline. The quieter one is that the library field is not where most of the problem lives. Images already placed in posts carry their own copy of the alt, and editing the library does not touch it.

An accessibility overlay

The pitch is one script tag and the audit problem disappears, and the deployment really is that fast. What the script does is patch the rendered page in the visitor's browser, including machine-guessed text alternatives. The Overlay Fact Sheet, signed by over 1,000 practitioners including screen reader developers, is blunt about that part: automated text alternatives for images are not reliable. Blind users quoted in the fact sheet describe sites that became less usable after an overlay went in, and in 2025 the FTC ordered one overlay vendor to pay $1,000,000 over claims that its AI could make any site WCAG-compliant. Your content still has no alt text. The fix lives in a third party's JavaScript, for exactly as long as you keep paying.

An alt-text generator plugin

The category works two ways: generate a description the moment an image uploads, and run a bulk pass over the existing library, usually priced per image in credits. On-upload generation is worth having; it is the only thing on this page that stops the backlog from regrowing. The bulk pass is where the category gets thin. The text writes straight to the live field, typically with no review queue, so a real description and "image of a houseplant" ship with the same authority, and decorative images get described instead of marked decorative. The budget end of the category converts filenames into alt by stripping the hyphens, which ships the exact failure your audit flagged, and vendors' own guides advise a database backup first because the pass does not undo.

Scratch plus the alt text skill

Scratch pulls your posts and media library into files on your laptop, and your own agent, Claude, Codex, Cursor, or Copilot, does the describing with the alt text skill as the brief. The agent writes a validator for your rules, drafts against it, and skips images it cannot make a confident call on. It works from the filename, the caption, and the surrounding prose, and from the image itself where your agent reads images. One boundary the skill page calls out: posts built in a page builder such as Elementor or Divi keep their images in serialized layout data, not post HTML, and need a different mapping than this pass. Every new description comes back as a word-level diff next to the old one, and only what you approve publishes. The trade is stated plainly: confirming that a description matches the actual photo is human reading, and Scratch leaves that work to you on purpose.

Option Every image Judgment in context Review before live Undo after publish
Media library by hand Eventually Yes, a person looks You are the review By hand
Accessibility overlay Claims to Not reliable, per the Fact Sheet No Only by removing the script
Alt-text generator plugin Yes, per credit Unchecked, typically no queue Typically no Typically no
Scratch Yes, minus what the agent honestly skips Yes, your agent with your rules Every change, as a diff Per item, even after publish

How the loop works on your library

  1. Scratch pulls your posts and media library into files. Each post lands as its own file in the WordPress REST shape, with every in-post image tag and its alt inside content.raw, and the media library's alt fields come along as editable content of their own. Now the census is cheap. Over the REST API, attachments arrive at most 100 to a page, so just listing 4,800 of them is 48 round trips at best before you have read a single post body. On local files, one grep counts every missing and empty alt in about a second. Nothing on the live site has changed.
  2. Your agent writes the descriptions. Point your agent at the folder and paste the skill prompt, or give it the short version: Write alt text for every image that is missing it or carrying filler. Describe what the image does in this post, give decorative images an empty alt, never open with "image of", and skip anything you cannot support from the file, the caption, or the surrounding prose. Per the skill, the agent reads a sample first, asks about your conventions, writes a validator at .scratch/validators/, and edits one post for sign-off before touching the rest. It can also build an index of which attachment appears in which posts and flag where the library and the in-post copies disagree. It holds no API token, so it cannot touch the live site.
  3. You review every diff and publish. The validator screens the mechanical failures first: missing alt, filler openers, filename-as-alt, duplicates within a post. Your reading goes to the one judgment no script can make: do the words match the photo? The agent did 99% of the work in step 2. That match is the 1% that was always yours. Approve, and Scratch writes back over the WordPress REST API at the API's own pace, one approved item at a time, with a log of what went out. A description that reads wrong an hour after publish reverts per item, and the original goes back.

Run the first pass on one category, or the 50 posts that get the most traffic. When those diffs read right, send the agent through the rest of the library. The skill page has the full prompt, including the validator step and the one-post sign-off.

The two places WordPress keeps alt text

WordPress stores an image's alt text on the attachment itself, as the field you see in the media library. The moment you insert that image into a post, WordPress copies the alt into the post's HTML, and the copy never looks back. Edit the library field tomorrow and every image already sitting in a post keeps the alt it was inserted with. The same photo used in 2 posts can carry 3 different alt texts, one in each post plus the library's. Featured images are the exception; they render their alt live from the library field.

This is how a site passes the library check and still fails the page audit: most bulk fixes touch one location and call it done. Files make both visible. The in-post copies live in each post's content.raw, where the skill edits. The library field is editable alongside them. And the split is not only a trap, it is also the point: the same screenshot can honestly mean different things in a tutorial and a changelog, and in-post alt is where that difference gets written.

Questions people ask

Does fixing alt text in the media library fix the images already in my posts?

No. WordPress copies the library alt into the post HTML when the image is inserted, and the two never sync afterward. Library edits fix the library, future inserts, and featured images, which render alt live from that field. The 4,800 copies already sitting in post content keep whatever they were inserted with, which is why the loop pulls the posts too.

Do decorative images need alt text?

Yes. The correct value is present but empty: alt="" tells a screen reader to skip the image. Removing the attribute entirely is a documented WCAG failure, because the reader falls back to the filename, and writing filler on a decorative image is a documented failure too. The W3C publishes a decision tree for the borderline calls, and the skill's brief follows the same logic.

Can the AI actually see my images?

Sometimes. It depends on the agent you bring. Where your agent can view images, the skill uses the image itself. Otherwise it works from the filename, the caption, and the prose around the image, which is usually enough for a confident description. When it is not, the skill tells the agent to leave that image alone and list it as skipped. Nothing gets a made-up description to hit a quota.

Is wrong alt text really worse than none?

It can be. University digital accessibility offices state it plainly: an incorrect alt attribute conveys false information to assistive technology users. A missing one typically falls back to the filename, which at least warns the listener something is unlabeled. Screen reader users also report recognizing machine-written alt within seconds when it lists elements instead of meaning. That is the whole case for the review step. False descriptions should die on your screen, not live on your site.

Will this help image SEO?

It can. Google says it uses alt text, along with computer vision and the page contents, to understand what an image shows, and the same document warns that stuffing keywords into alt can get a site treated as spam. You may also meet an SEO plugin that grades you up for putting the keyphrase in a share of your image alts. Write for the screen reader first and let the keyword appear where it is honestly descriptive. WCAG does not care about keywords at all.

How long should each description be?

Short. A few words to a sentence, accurate about what the image does in the post, never opening with "image of" or "photo of", since screen readers already announce that it is an image. The 125-character ceiling you see quoted is industry convention, not a WCAG rule. The working test is that a screen reader gets through it in one breath.

Is my site unusually bad?

No. WebAIM's 2025 scan of the top 1,000,000 home pages found missing alt text on 18.5% of images, and missing alt appeared on roughly 55% of the home pages checked. The skipped field is the norm, not your team's failure. Your screen reader users do not grade on a curve, but you are not cleaning up a rare mess.

Do I need to be technical?

No. If you can caption a photo, you can do the review; the agent does the file work, including writing the validator. You install a desktop app, connect WordPress, and paste a written prompt. Your part is reading each new description next to the old one and clicking approve or reject.

See it on your own media library

The census takes about a minute once the files are local. See it run on your media library →, or download Scratch free, pull your posts, and ask your agent how many images are missing alt before you decide anything else. The number alone is worth the download.

See it run on your own content.

Curtis runs these calls himself. Thirty minutes, no pitch, no slides. He connects your platforms live and shows you your content as an editable, reviewable diff. Bring anything sticky: a refresh, a migration, or a rebrand.

See it run on your content → or download it free