Text in images SEO: what crawlers miss in canvas and video
Text in images, canvas and video is not in the HTML crawlers read. How to find words locked in pixels on your pages, and the alt text and transcript fixes.
By Crawlito · 8 min read
In short
Crawlers index the text in your HTML; words baked into a banner image, drawn on a canvas or spoken in a video are not part of that text.
OpenAI, Anthropic and Perplexity do not document running OCR on page images in their crawler documentation, so treat text in images as missing for AI search.
Google says it does not index CSS background images, so a hero built from a background image and baked-in text gives Google nothing to read.
Inline SVG text written as text elements stays readable; text converted to outlines in a design tool becomes path data with no words in it.
Alt text, canvas fallback content, on-page transcripts and VideoObject markup put the same information back into the HTML where crawlers look.
Crawlers read text, not pixels. If a heading, offer or explanation exists only inside an image, a <canvas> drawing or a video, it is not in the text a crawler extracts from your page, and AI search tools have nothing to quote. The fix is to put the same words in the HTML, as real text, alt text, fallback content or a transcript, and to check the raw HTML to confirm they are there.
Why crawlers miss text that people can see
A crawler fetches your URL, takes the HTML, and turns it into text. Images, canvas bitmaps and video frames are not text. They are files or pixels that a person reads with their eyes.
Three documented facts make this concrete:
The AI crawlers measured in 2024 did not run JavaScript. The Vercel and MERJ analysis (December 2024) found that none of the major AI crawlers it measured rendered JavaScript at the time, including OpenAI's crawlers, ClaudeBot and PerplexityBot. Anything drawn by a script did not exist for them. Our post on whether AI crawlers run JavaScript covers the detail.
Fetching an image is not reading it. The same analysis found images made up 35.17% of Claude's fetches on nextjs.org at the time. That shows the crawler downloaded image files. It does not show that it read any words inside them, and none of the crawler documentation from OpenAI, Anthropic or Perplexity says their crawlers run OCR on page images.
Google treats images as images. Google's image SEO guide says it uses alt text along with computer vision algorithms and the contents of the page to understand images, and that "Google doesn't index CSS images." Understanding that a photo shows a running shoe is not the same as indexing the sentence "Free returns for 90 days" painted across it.
So the safe working rule for AI search is simple: if a word is not in the HTML as text, assume no crawler has it.
Where text gets locked in pixels
Pattern
What the crawler gets
Typical example
Text baked into an <img>
The file URL and the alt attribute, if any
Hero banner with the headline in the JPEG
Text in a CSS background image
Nothing; Google says it does not index CSS images
Promo strip set with background-image
<canvas> drawing
The fallback content inside the tag, if any
Charts, configurators, pricing calculators
Video or animation
The surrounding page text and any markup
Product explainer with no written version
SVG with text converted to outlines
Path coordinates, no words
Logo-style headings exported from Figma or Illustrator
SVG loaded with <img src="...svg">
The alt attribute; the SVG's own text is a separate file
Infographics
Logos are the one place an image of text is normal and fine. WCAG's Images of Text criterion makes the same exception for logotypes. The problem is everything else: headings, prices, offers, step-by-step instructions and answers to the questions people ask.
How to check your page for text in images
Pick one sentence you care about, such as your main headline or a key product claim, and look for it in the HTML a crawler receives. Our guide to seeing your page as an AI crawler with curl explains the method; here is the short version.
Fetch the raw HTML with a crawler user agent and search for the phrase:
bash
curl -sL -A "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot" \
https://example.com/ | grep -ci "free returns for 90 days"
The command counts matching lines. A result of 0 means the words are not in the HTML that crawler gets. The user agent string is OpenAI's documented example for GPTBot; the version number may change.
List every image and its alt text, so you can spot banners with empty or missing alt:
The first command lists the image tags; the second prints images with no alt text or an empty alt="". Empty alt is correct for decoration, but not for a banner that carries your headline.
Many SVGs are icons with no words at all. But if an inline SVG shows lettering and the count has <svg with no <text, that lettering is paths, not text.
Compare with what a person sees. Open the page, select all the text with your cursor, and note what will not highlight. Text you cannot select is usually part of an image, a canvas or a video. Comparing raw and rendered HTML catches the related problem of text that only a script adds.
How to fix hero banners with baked-in text
Keep the photo as an image and move the words into HTML on top of it. CSS handles the visual overlay, and the heading becomes a real <h1> that crawlers, screen readers and translation tools can read.
html
<section class="hero">
<img src="/img/hero-runner.jpg" alt="Runner on a coastal trail at sunrise" width="1600" height="900">
<div class="hero-copy">
<h1>Trail shoes built for wet rock</h1>
<p>Free returns for 90 days. Ships in two working days.</p>
<a href="/shop/trail">Shop trail shoes</a>
</div>
</section>
Two details matter. The alt describes the photo, not the headline, because the headline is now on the page in its own right. And if you use a CSS background image instead of <img>, that is fine for decoration, but put every word that matters in the HTML. A good heading structure helps here too: see headings, landmarks and link text.
If you cannot change the template yet, write alt text that carries the message: alt="Trail shoes built for wet rock. Free returns for 90 days." It is a stopgap. Alt text is short, it is not body copy, and it sits in an attribute rather than in the visible text of the page, so you cannot count on every tool that extracts page text to keep it.
How to make canvas content readable
Canvas draws pixels with JavaScript. A crawler that does not run scripts sees an empty tag, and even Googlebot, which renders with Chromium, ends up with a bitmap rather than words. The HTML standard says authors should not use canvas when a more suitable element exists, that a page heading is an inappropriate use, and that when you do use canvas you must provide content that conveys the same information.
That required content is the fallback inside the element:
html
<canvas id="price-chart" width="800" height="400" aria-describedby="price-chart-summary">
<p id="price-chart-summary">
Plan prices in 2026: Starter $12 per month, Team $39 per month, Business $99 per month.
</p>
<table>
<tr><th>Plan</th><th>Price per month</th></tr>
<tr><td>Starter</td><td>$12</td></tr>
<tr><td>Team</td><td>$39</td></tr>
<tr><td>Business</td><td>$99</td></tr>
</table>
</canvas>
Fallback content sits in the HTML, so it is there before any script runs. For bigger canvas apps, such as product configurators, maps or design tools, render the facts that matter as normal HTML next to the canvas: the product name, options, prices and a short description. Put it in the server response, not in a script, for the same reason covered in client-side rendering and the empty HTML problem.
SVG text vs outlined paths
SVG can hold real text or just shapes, and the difference is invisible on screen.
html
<!-- Readable: the words are in the markup -->
<svg viewBox="0 0 400 80" role="img" aria-labelledby="t1">
<title id="t1">Same-day delivery in Berlin</title>
<text x="0" y="50" font-size="40">Same-day delivery in Berlin</text>
</svg>
<!-- Not readable: the same words converted to outlines -->
<svg viewBox="0 0 400 80">
<path d="M12.4 48.1c-3.2 0-5.9-1.1-8.1-3.3l2.2-2.6c1.6 1.6 3.6 2.5 5.9 2.5..."/>
</svg>
Design tools often convert text to outlines on export so the font looks the same everywhere. That turns the words into path data. Three fixes:
Export with live text, or rebuild the heading in HTML and CSS with a web font.
For inline SVG, add a <title>. Google's image guide says that for inline <svg> elements you can use the <title> element in place of alt text.
For an SVG used as <img src="chart.svg">, give it alt text. Its internal <text> lives in a separate file, not in your page's HTML.
How to make video and animation readable
A video explains things well to people and says nothing to a crawler that reads HTML. Google's video guide says Google can find videos referenced by <video>, <embed>, <iframe> or <object> elements, recommends a watch page with a title and description unique to the video, and says the structured data should match the video content. None of that turns the spoken words into page text.
Put them there yourself:
Publish a transcript on the page, as normal HTML under the video, or a cleaned-up written version with headings. This is the fix that matters most for AI search.
Add captions with <track>. The track element points to a WebVTT file. It helps people, but the text lives in a separate .vtt file, not in the page HTML, so do not rely on it as your crawlable copy.
Add VideoObject markup with name, description, thumbnailUrl and uploadDate, and schema.org's transcript property if you want the text in the markup too. Keep it consistent with the visible transcript.
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "How to fit a trail shoe",
"description": "A two-minute guide to sizing trail shoes for long runs.",
"thumbnailUrl": "https://example.com/img/fit-guide.jpg",
"uploadDate": "2026-10-01",
"contentUrl": "https://example.com/video/fit-guide.mp4",
"transcript": "Start with your longest toe. Leave a thumb's width of space..."
}
</script>
Animated text in a GIF, a Lottie file or a scroll-driven sequence has the same problem. If the animation carries a message, write the message in HTML as well. Google's AI features are no exception: as covered in the technical requirements for AI Overviews, a page has to be indexed and eligible for a snippet, and a snippet is built from text.
Writing alt text that does the job
Describe what the image shows and why it is on the page, in one or two plain sentences.
If the image contains text that matters, include that text, or better, move it into the HTML.
Use alt="" for purely decorative images so screen readers skip them.
Do not stuff keywords. Alt text is read aloud to screen reader users, and a list of keywords helps no one.
Do not repeat the caption word for word if a visible caption already says the same thing.
Frequently asked questions
Can Google read text inside images?
Google says it uses alt text along with computer vision and the page's content to understand images, in its guide to image search. It does not say it indexes the words painted into an image as page text, and it does not index CSS background images at all, so put important text in the HTML.
Do ChatGPT, Claude or Perplexity run OCR on my images?
The crawler documentation from OpenAI, Anthropic and Perplexity does not say their crawlers run OCR on page images. Their crawlers do download image files, but that is not evidence that the words inside are read, so treat image-only text as missing.
Is alt text enough to fix a text-heavy banner?
It is a reasonable stopgap, not a full fix. Alt text is short and lives in an attribute; a real heading and paragraph in the HTML carry more information and keep the page structure clear.
Does SVG count as text for crawlers?
Only when it contains real text. Inline SVG with <text> elements keeps the words in the markup; SVG text converted to outlines is path data, and an SVG loaded through <img> is a separate file that needs its own alt text.
Should I stop using video?
No. Keep the video for people and add a transcript or written summary on the same page, so crawlers that read HTML get the same information.
Check your pages for locked text
Start with the pages that matter most: your home page, top product or service pages, and any page built around a banner or a video. Run the curl test above on each of them. If you want a second view, the free single-page check needs no account, and a full audit covers up to 500 pages with human review and a PDF of prioritized fixes with the evidence for each.
Filed under Rendering and content. Topics: · rendering, ai-crawlers, google, javascript
Do AI crawlers render JavaScript? Googlebot does. Most AI crawlers did not in Vercel's 2024 study. What that means for your pages and how to test them.
Raw HTML vs rendered HTML: what each one is, how to compare them with view-source, curl, DevTools and Search Console, and when the gap hides content from crawlers.
Client-side rendering can hand AI crawlers an empty HTML shell. See what they receive, the symptoms, the fixes ranked by effort and how to verify each one.