BlogFindings
173 of 466 images carried alt text a crawler could read
Counted with an HTML parser over five real pages this scanner captured and stored on 15 July 2026, the rendered DOM held 466 img elements: 173 with a non-empty alt attribute, 246 with an explicitly empty one, and 47 with no alt attribute at all. Our own extractor reads none of them.
So we went back to the captures this scanner keeps as golden fixtures and counted, because the question is answerable from data already sitting in the repository rather than from an opinion about best practice. Those fixtures are real pages fetched and rendered on 15 July 2026 and committed so that a change in scoring has something fixed to be measured against. They were captured to exercise prose parity and the rest of what the scoring engine does, not to study images, and that is the useful thing about them: nobody chose these pages for how well they handle alt text.
In short
- Five real pages stored as golden fixtures in this repository, captured on 15 July 2026, held 466 img elements in their rendered HTML: 173 with a non-empty alt attribute, 246 with an empty one, and 47 with no alt attribute at all.
- An empty alt is correct rather than broken: the W3C Web Accessibility Initiative tutorial on decorative images, updated 27 July 2019, states that a null (empty) alt text should be provided so such images can be ignored by assistive technologies, and that leaving the attribute out is not an option.
- Google's Google Images documentation, carrying Last updated 2026-03-02 UTC, states that Google uses alt text along with computer vision algorithms and the contents of the page, so alt is one of three inputs for Google and the only one of the three that lives in the markup.
- Lantad's extractor in core/src/extract.ts reads six attributes off the elements it walks and alt is not among them, so all 173 descriptions counted here are absent from our word count, our parity comparison and our grade.
- The same five captures held 276 inline svg elements carrying 137 characters of text between them, so dropping svg cost these particular pages very little, and would cost a page of drawn diagrams its labels.
What a text extractor does when it reaches an image
An HTML parser walks a tree of elements and collects the characters between tags. An img element has no characters between its tags because it has no closing tag: it is a void element, its content is a file at the other end of a src attribute, and the parser arrives, finds nothing to collect, and moves on. Whatever the image depicts is in a JPEG or a WebP at another URL, and it is not in the document.
That leaves exactly one channel inside the markup. MDN's reference for the img element, last modified 2026-05-09, describes alt as holding a textual replacement for the image, and notes that alt text is also displayed on the page if the image cannot be loaded, listing network errors, content blocking and link rot as the reasons. A parser is a fourth case that list does not name. It is a client that never requests the image at all, so for it the replacement is not a fallback shown after a failure. It is the entire content, every time.
Whether any particular crawler reads that attribute is a property of that crawler's extraction code, and it is not observable from outside a site. What is observable, and what this post is willing to state, is the shape of the problem: text that exists only as pixels cannot be recovered by any amount of parsing, and text that exists in an alt attribute can be recovered only by a parser that chooses to look there. This is the same class of failure as text inside a shadow root, where the words are plainly present in the browser and plainly absent from what a simple fetch returns, and it is why a check of what GPTBot sees reports on delivered HTML rather than on a screenshot of the page.
Flow: HTML response to Parser walks the tree; Parser walks the tree (prose between tags) to Text node; Parser walks the tree (no text content) to img element; img element (if the reader looks) to alt attribute read; img element (if it does not) to Nothing extracted.
How many images on five captured pages carried a description
Six of the golden fixtures are captures of real sites rather than synthetic test documents. One of them, allbirds.com, answered 429 on 15 July 2026 and was never rendered, so it holds no DOM to count. Of the five that returned 200 and rendered, four carried img elements at all. The fifth is a documentation landing page on developer.mozilla.org and it carries none, which is worth a moment on a page about HTML.
Counting img elements in the stored rendered HTML with a standard parser gives 466 across those five captures. Of those, 173 carry an alt attribute with something in it, 246 carry an alt attribute set to the empty string, and 47 carry no alt attribute at all. The distribution is lopsided in the ordinary way: two homepages, one of them a storefront of the kind covered in our Shopify guide and the other a website builder's marketing page, hold 413 of the 466 between them, because a homepage built to sell something is mostly a grid of pictures, which is the same reason a crawler meets so little prose on a real storefront. Wikipedia's article on web crawlers holds 12 and astro.build holds 41.
Two limits on this figure, stated because they change how it should be read. The count is of img elements in the rendered DOM, so it includes navigation icons, footer badges, payment logos and product tiles, and it makes no attempt to separate an image that carries meaning from one that decorates. And five pages is five pages. This is a count of what sits in our fixture set on one day, not a survey, and we have run no survey of alt text across any sample large enough to generalise from. The crawlability study we do publish measures other things entirely, and nothing in how we score AI visibility currently looks at an alt attribute at all. What these five pages support is a description of one real corner of the web, which is more than a best-practice article usually offers and considerably less than a statistic.
| Captured page | img elements | Non-empty alt | Empty alt | No alt attribute |
|---|---|---|---|---|
| gymshark.com | 237 | 70 | 123 | 44 |
| webflow.com | 176 | 63 | 113 | 0 |
| astro.build | 41 | 33 | 8 | 0 |
| en.wikipedia.org/wiki/Web_crawler | 12 | 7 | 2 | 3 |
| developer.mozilla.org/en-US/docs/Web/HTML | 0 | 0 | 0 | 0 |
| Total | 466 | 173 | 246 | 47 |
An empty alt is correct, and a missing alt is not
The largest of the three counts is the one that is not a defect. An empty alt is a declaration, and it is the declaration the specifications ask for. The W3C Web Accessibility Initiative tutorial on decorative images, updated 27 July 2019, states that a null (empty) alt text should be provided so that such images can be ignored by assistive technologies such as screen readers, and states in the same passage that leaving out the alt attribute is also not an option, because when it is not provided some screen readers will announce the file name of the image instead. MDN states the same rule from the other side: setting the attribute to an empty string indicates that the image is not a key part of the content, and it gives decoration and a tracking pixel as its two examples.
So 246 empty attributes is 246 authors saying, correctly, that a divider or an icon or a background flourish carries nothing a reader needs. Reported as a failure it would be a false finding, and a scanner that counted it as one would be selling alarm rather than measurement. The 47 with no attribute at all are a different matter. They are the ones that leave a machine with no way to tell an image that matters from one that does not, and on the storefront capture there are 44 of them.
The other half of the picture is what a search engine does with the attribute when it is present. Google's Google Images documentation, carrying Last updated 2026-03-02 UTC, states that Google uses alt text along with computer vision algorithms and the contents of the page to understand the subject matter of the image. That is three inputs, of which alt is one, and of which only one lives anywhere a text extractor can reach. Google looking at the pixels is a documented capability of Google. It is not a property of text extraction, and no crawler documentation we have read claims it for any AI crawler.
-
alt with text in itReadable A parser that reads the attribute gets a description. 173 of 466 in these captures. -
alt set to the empty stringDeclared decorative What the W3C WAI tutorial asks for on an image that adds no information. 246 of 466. -
no alt attributeUndeclared The same tutorial says some screen readers announce the file name instead. 47 of 466.
Our own extractor reads no alt attribute either
The inconvenient part of this post is what our own scanner does with all 173 of those descriptions, which is nothing. The extractor in core/src/extract.ts walks a document and reads exactly six things off the elements it passes: the lang attribute on html, the text inside title, the name and content pair on meta, the href on a link whose rel includes canonical, the type on input so that a password field can flag an auth wall, and the type on script so that JSON-LD and inline JSON reach the harvester. There is no seventh. An img element is not dropped and not treated specially, it simply contributes nothing, because there are no characters between its tags and nobody looks at its attributes.
That means every description counted in this post is invisible to our word count, invisible to the parity comparison between the raw fetch and the rendered page, and invisible to the grade a report prints. It is a real gap in what we measure, and naming it is preferable to letting a reader assume otherwise, which is the same instinct behind withholding a grade on a page we could not measure rather than scoring the part we did reach.
Whether it should change is a genuine question rather than a rhetorical one, and the answer is not obviously yes. Counting alt text as prose would inflate the word count of an image-heavy page with a colourway name repeated forty times down a product grid, and it would reward stuffing the attribute, which Google's own guidance warns against in the documentation quoted above. Counting it separately, as its own signal alongside structured data, is the more defensible design, and it is not built. Until it is, the honest statement is the one already in our methodology: the score describes the text a parser recovers from the delivered HTML, and the meaning of an image is not in that text.
- lang on html Stored as the document language.
- text inside title Stored as the page title.
- name and content on meta description and robots are both kept.
- href on link rel=canonical Stored as the declared canonical URL.
- type on input A password field flags the auth wall state.
- type on script Routes JSON-LD and inline JSON to the harvester.
- alt on img Not read. An img contributes nothing to the extracted text.
Inline svg held 276 elements and 137 characters of text
Images are not the only way words leave the text stream. Inline svg puts real characters into the document, inside text and tspan elements, and a parser that descended into svg would find them. Ours does not: svg sits on the extractor's drop list beside script, style, noscript, template and iframe, which is the same drop list we described when writing about shadow DOM.
So we counted that too. The same five captures hold 276 svg elements, and inside all of them together, 25 text, tspan, title or desc children carrying 137 characters between them once whitespace is trimmed. Almost all of it is on one page: webflow.com accounts for 124 of the 137 characters and 22 of the 25 elements, while astro.build's 195 svg elements carry no text whatsoever. On these pages inline svg is iconography, and dropping it costs the extraction 137 characters, which is shorter than this sentence and the one before it.
That is a smaller number than the argument for parsing svg would predict, and saying so is better than leaving an impression of some large hidden loss. The risk it points at is real but narrow. It lands on pages where a diagram, a chart or a pricing comparison was drawn rather than written, and on those pages the drawn labels are the content rather than the decoration.
It is also why the diagrams on this site are built the way they are. The visual system in the site source lays a process diagram out server side into inline svg, with no client JavaScript, and then prints a plain-text summary of the same nodes and edges beside it, so a client that skips svg still reads the sequence. Every page here also carries a markdown twin at its own address, and the developer reference describes how to fetch one. Neither is a clever trick. Both exist because assuming your reader parses everything you drew is how content goes missing.
| Captured page | svg elements | Text-bearing children | Characters of text |
|---|---|---|---|
| astro.build | 195 | 0 | 0 |
| webflow.com | 68 | 22 | 124 |
| gymshark.com | 9 | 0 | 0 |
| developer.mozilla.org/en-US/docs/Web/HTML | 4 | 3 | 13 |
| en.wikipedia.org/wiki/Web_crawler | 0 | 0 | 0 |
| Total | 276 | 25 | 137 |
What to check on your own page
None of this needs a scanner. Open the page, turn images off in the browser, and read what is left. The words that vanish are the words no parser will ever recover, and on a commerce page the thing that vanishes is often the offer itself. Then view the delivered source and search for img elements carrying no alt attribute, which was the 10 percent case across our five captures and the only one of the three states that is unambiguously a gap rather than a decision.
Read the alt values rather than counting them, because a count says nothing about quality. An attribute containing a file name is present, valid and useless, and it will pass any check that merely looks for the attribute's existence. Google's guidance in the documentation quoted earlier is that alt text should be useful and information rich and in the context of the page, and that stuffing it with keywords may cause a site to be seen as spam, which is a reminder that something on the other end judges the string rather than just recording it.
The last check is the one most often skipped: find the words that exist only inside an svg or a canvas element and make sure the same words exist somewhere else on the page as well. A caption under the diagram, a paragraph restating what it shows, a table beside it. That costs a few sentences and it is the whole difference between a page that explains itself to a parser and a page that explains itself only to an eye.
If you want to know which clients reach your pages at all before deciding how much of this is worth your time, the AI crawler reference lists the tokens we track, and the guide to being cited in Google's AI Overviews covers the surface where images and text are most often summarised together. Neither of them can tell you what an image says. Nothing can, except writing it down.
| Check | How to run it | What a failure looks like |
|---|---|---|
| img elements with no alt attribute | Search the delivered HTML for img and count those without alt | A product grid where every tile is undeclared |
| Words that exist only as pixels | Load the page with images blocked and read what remains | A headline claim, a price or a spec table disappears |
| Diagram labels inside svg | Search for text or tspan inside svg, then look for the same words in prose | A pipeline diagram whose only labels are drawn |
| alt that repeats the file name | Read the alt values rather than counting them | alt set to hero-banner-final-2.jpg |
Lantad
Published .
A page can be full of words a reader can see and still hand a text extractor almost none of them, because some of those words are pixels rather than characters. A price set into a promotional banner, a specification table exported as a PNG, a diagram whose labels were typed in the design tool: all of it renders, none of it parses. The alt attribute is the one place in the markup where those words can be written down again in a form a machine reads, which makes alt text a readability question and not only an accessibility one for anyone who cares whether an AI crawler can reconstruct what a page says.
Common questions
Do AI crawlers read alt text?
That is a property of each crawler's extraction code and it is not observable from outside a site, so this post does not claim an answer for any vendor. What can be stated is the mechanism: an img element carries no text between its tags, so the alt attribute is the only place in the markup where an image's meaning can be written down, and a parser recovers it only if it chooses to read attributes. Lantad's own extractor does not.
Is an empty alt attribute a problem?
No. The W3C Web Accessibility Initiative tutorial on decorative images, updated 27 July 2019, states that a null (empty) alt text should be provided so decorative images can be ignored by assistive technologies, so an empty alt is the correct declaration for an image that adds no information. The state that is a problem is an img element with no alt attribute at all, which was 47 of the 466 elements counted in our five captures.
Does the Lantad AI Visibility Score include alt text?
No. The extractor in core/src/extract.ts reads six attributes while walking a document, being lang on html, the text in title, name and content on meta, href on a canonical link, type on input and type on script, and alt is not among them. Alt text therefore contributes nothing to the word count, nothing to the prose parity comparison and nothing to the grade. Adding it as a separate signal is a design question we have not settled.
What happens to text inside an inline SVG?
Lantad's extractor drops svg subtrees entirely, along with script, style, noscript, template and iframe, so any text in an svg element is not extracted. On the five pages captured on 15 July 2026 the cost of that was small: 276 svg elements held 137 characters of text between them, almost all on one page. The cost is much higher on a page whose diagrams or charts carry their labels only as drawn text.
See what AI can read on your site
Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.