Home · The 15 signals · Image alt text
Shopify image alt text for AI shopping agents
Image alt text is the cheapest 6 ranking-spread points in the entire 15-signal suite — and the one fewest stores collect. Every Shopify store CatalogScan has scanned has alt-text coverage below 30%; many are at 0%. The signal is purely "did your team type a sentence per image" and the payoff is direct: AI shopping agents use alt text to pick up product attributes that aren't in the description — color shown in the image, fabric drape, model height-to-product ratio, the angle of view, whether a shoe is photographed on or off a foot. When a query is "running shoe with a wide toe box visible in the side profile," the only signal in your catalog that can match it is alt text.
images[].alt entries that are non-empty across a sample of your /products.json feed. Full credit (6 pts) at ≥80% non-empty alts; half credit (3 pts) at 30-79%; zero under 30%. We sample the first 30 products' first three images each — 90 images total per scan.
What it is
Every product image in Shopify has an alt field, exposed in three places:
- The Shopify Admin → Products → product → image gallery → click an image → "Edit alt text."
- The Storefront API
Imageobject'saltTextfield. - The public
/products.jsonfeed atproducts[].images[].alt.
When a product image renders in HTML — either via {% raw %}{{ image | image_tag }}{% endraw %} in Liquid or via your Hydrogen/Next.js component — the alt field renders as the alt="" attribute on the <img> tag. Browsers and screen readers and AI agents all read the same field.
Empty alt
<img alt="" src="...">
{ "alt": null }
Filename used as alt
<img alt="IMG_3492.jpg" src="...">
{ "alt": "main-shoe-1.png" }
Just the product name
<img alt="Wool Runner" src="...">
{ "alt": "Wool Runner" }
Product + visual attribute
<img alt="Wool Runner in Natural Grey, side profile, on white background" src="...">
{ "alt": "Wool Runner in Natural Grey, side profile..." }
Why AI shopping agents care
- Attribute pickup the description misses. Descriptions tell agents what the product is. Alts tell them what the image shows. A description for a t-shirt might say "100% cotton, crewneck, regular fit"; the alt for the third image says "shown in heather grey, on a 5'10" model, hits at the hipbone." That second sentence answers a different class of customer query than the description.
- Per-image specificity. One product has 3-8 images, each captured from a different angle, on a different model, in a different colorway. Each alt is a separate text-matching anchor. Agents that surface specific images (Perplexity, Google AI Mode in image-rich answers) pick the image whose alt best matches the query — without distinct alts, you score the same on every image and the agent picks one effectively at random.
- Trust priming. AI rankers note alt-text coverage as a "well-tended catalog" signal — a proxy for the kind of operator who's also going to have GTINs, descriptions, and review schema in good shape. The alt-text signal correlates highly with overall catalog hygiene; rankers use it as a fast pre-filter.
- Accessibility halo. Alt text is also the WCAG accessibility requirement for images. AI rankers have begun lightly weighting accessibility-positive signals (proxy for legitimacy and trust), and broken alt-text coverage downweights you on the same axis. One field, two systems benefit.
How to test it on your store
One curl + jq measures coverage in one second:
curl -s https://yourstore.com/products.json?limit=30 \
| jq '[.products[].images[].alt] | length as $t
| map(select(. != null and . != "")) | length as $f
| "\($f)/\($t) = \($f * 100 / $t | floor)%"'
Expected output: a fraction and a percentage. Anything under 80% is a problem; anything under 30% is the most common case. The free CatalogScan scan runs this same check across the first 30 products and reports the percentage with examples of the worst offenders.
What good alt text looks like (8-15 words, recipe)
| Pattern | Product name + colorway + visual attribute + angle/context |
| Apparel | "Cotton crewneck tee in heather grey, front view on 5'10" model" |
| Footwear | "Wool Runner in Natural White, side profile showing wide toe box" |
| Cookware | "10-inch nonstick frying pan, top-down view, wooden countertop background" |
| Beauty | "Vitamin C serum 30ml glass dropper bottle, lifestyle shot on bathroom shelf" |
| Furniture | "Mid-century walnut accent chair, three-quarter angle, in living room context" |
| Electronics | "Wireless earbuds in charging case, hand for scale, charcoal grey" |
Each is 8-15 words, leads with the product, then the colorway/variant, then the distinguishing visual attribute. Skip "image of," "photo of," "picture of" — the parser knows it's an image. Skip emoji and decorative punctuation — they're noise in the embedding match.
How to fix it
Shopify admin → Products → click into each product → click each image → "Edit alt text" → type the 8-15 word alt. Tedious, but for catalogs under 100 products it's the cleanest path. Train one team member on the recipe and it's done in a sitting.
Install Matrixify. Export Products with the Image columns. Edit Image Alt Text in the spreadsheet — bulk-fill from a formula like =A2&" in "&B2&", front view" using product name and color columns. Re-import. Catalogs of any size move in one batch. Verify a sample by viewing the product after import.
Write a one-off Node or Python script using the Admin API productImageUpdate mutation. Iterate every product, generate alts from the product fields you already have (title, vendor, product_type, the active variant's color option), PUT the new alt to the image. Rate limit: 4 mutations per second on standard plans, 40/sec on Plus. A 1,000-product catalog takes ~5 minutes.
// Pseudocode — fill in client + auth
for (const product of allProducts) {
for (const image of product.images) {
const alt = `${product.title} in ${product.options[0].values[0]}, view ${image.position}`;
await admin.productImageUpdate({ id: image.id, alt });
}
}
Pro pulls each image, runs Claude vision over it with the product context, generates a brand-voiced 8-15 word alt that names the visual attributes the image actually shows, and writes it back via the Admin API. Per-image diff approval before write. See Pro pricing. The bulk-fill paths above use the data you already have; the vision path picks up attributes (lifestyle context, model demographics, scene framing) only the image itself reveals.
5 mistakes we keep finding
1. Filename as alt by default
Some Shopify themes default the alt to the image's original filename. Result: every alt is "DSC_3892.JPG" or "MAIN-shirt-blue-1.png" — pure noise to AI agents. The empty-string default is actually better than this; at least empty lets you pretend the image has no alt rather than telling the agent your alt is a filename. Override with the recipe above.
2. Alt is just the product name (half credit)
Many bulk-fill scripts emit alt = product.title verbatim. That's a partial — agents pick up the product name (which they already had from the product title) but get nothing about what the specific image shows. Add the colorway, the angle, the model, or the lifestyle context. Three extra words per alt buys the full 6 points.
3. Alt repeats across all images of a product
Every image of the same product gets the same alt. Defeats the per-image specificity that's the whole point — agents pick the wrong image for a query. Differentiate: image 1 is the front, image 2 is the back, image 3 is detail, image 4 is lifestyle. The recipe naturally produces this if you include angle/view in the recipe (front view / side profile / detail / lifestyle).
4. Stuffed with keywords (penalty risk)
Going the other direction: 30-word alt jammed with synonyms ("running shoe sneaker trainer athletic kicks footwear walking shoe..."). Search engines penalize this on the SEO side; AI rankers downweight it as low-quality text. Stick to 8-15 words of natural attribute description.
5. Headless front-end strips the alt during render
Some Hydrogen and Next.js storefronts use a generic <Image> wrapper that drops the altText field from Storefront API. The alt exists in the API response but never reaches the rendered HTML. Test view-source on a PDP — the <img alt=""> attribute should be your alt text, not empty. If empty, fix the wrapper component to pass altText through.
See also
- The 15 signals — full reference
- Description richness: the other text-matching signal
- Product JSON-LD: where the image array lives in structured form
- /products.json: the public feed where alts surface
- Full 18-signal Agentic Storefronts checklist
- Leaderboard: 100 DTC stores scored on alt text and 14 other signals
What's your alt-text coverage?
Free 2-minute scan. We sample 30 of your products, parse alt-text coverage across 90 images, and report the exact percentage alongside 14 other AI-shopping signals.
Scan my store → See all 15 signals