shopify-admin-agentic-image-alt-text
SkillMediaGenerate and set descriptive alt text on product images so AI agents (which can't 'see' pixels) can understand and recommend what each product looks like.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the shopify-admin-agentic-image-alt-text skill
What this skill tells your AI
The instructions your AI receives, as published by 40rty-ai/shopify-admin-skills in skills/agentic/shopify-admin-agentic-image-alt-text/SKILL.md and read by ahel’s review.
Purpose
An AI shopping agent reads image alt text to understand a product's appearance — color, material, style, use. Blank or filename-style alt text ("IMG_2931.jpg") tells the agent nothing, so it can't match the product to a visual query ("red linen midi dress") or describe it to a shopper. This skill finds product images with missing or low-value alt text and writes concise, descriptive alt text derived from the product's title, options, type, and tags. Fixes the agentiq.report finding listing-image-alt-text.
Prerequisites
- Authenticated Shopify CLI session (
shopify auth login --store <domain>) - Required API scopes:
read_products,write_products,write_files
Parameters
All skills accept these universal parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| format | string | no | human | Output format: human (default) or json |
| dry_run | bool | no | false | Preview mutations without executing |
Skill-specific parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| collection_id | string | no | — | Limit to a collection GID |
| tag | string | no | — | Limit to a product tag |
| overwrite | bool | no | false | If true, also rewrite filename-style / placeholder alt text; if false, only fill blanks |
| max_chars | int | no | 125 | Alt-text length cap (accessibility + agent-readability) |
Safety
⚠️ Step 3 (
fileUpdate) writes alt text to live media. Withoverwrite: trueit replaces existing alt text, which is not bulk-reversible. Rundry_run: truefirst and review the proposed alt text per image. Default (overwrite: false) only fills blanks and is low-risk.
Workflow Steps
-
OPERATION:
products— query Inputs:first: 250, optional collection/tag filter; fieldstitle,productType,tags,options,media{ MediaImage{ id image{ altText } } }; paginate until done. Expected output: Product media with current alt text + the product context needed to generate good alt text. -
COMPUTE (no API): for each image with blank (or, if
overwrite, placeholder) alt text, compose alt text fromtitle+ relevant option values (color/material/style) + product type, trimmed tomax_chars. Emit a preview table (image id → proposed alt). -
OPERATION:
fileUpdate— mutation Inputs:files: [{ id: <MediaImage id>, alt: <generated alt> }]in batches (≤ 25). Expected output: Updated files; collectuserErrors.
GraphQL Operations
# products:query — validated against api_version 2025-01
query AltTextProducts($first: Int!, $after: String, $query: String) {
products(first: $first, after: $after, query: $query) {
edges {
node {
id
title
productType
tags
options { name values }
media(first: 20) {
edges {
node { ... on MediaImage { id image { altText url } } }
}
}
}
}
pageInfo { hasNextPage endCursor }
}
}
# fileUpdate:mutation — validated against api_version 2025-01
mutation AltTextUpdate($files: [FileUpdateInput!]!) {
fileUpdate(files: $files) {
files { ... on MediaImage { id alt } }
userErrors { field message code }
}
}
Session Tracking
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: <skill name> ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝
After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>
If dry_run: true, prefix every mutation step with [DRY RUN] and do not execute it.
On completion, emit:
For format: human (default):
══════════════════════════════════════════════
OUTCOME SUMMARY
<Metric label>: <value>
Errors: 0
Output: <filename or "none">
══════════════════════════════════════════════
For format: json, emit:
{
"skill": "<skill-slug>",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": false,
"steps": [
{
"step": 1,
"operation": "<OperationName>",
"type": "query",
"params_summary": "<string>",
"result_summary": "<string>",
"skipped": false
}
],
"outcome": {
"metric_key": 0,
"errors": 0,
"output_file": null
}
}
Output Format
human: count of images updated + a CSV (product, image_id, old_alt, new_alt). json: { images_updated, images_skipped, errors, output_file }.
Error Handling
| Error | Cause | Recovery |
|---|---|---|
THROTTLED | API rate limit | Wait 2s, retry up to 3 times |
userErrors non-empty | Invalid file id / not a MediaImage | Log message, skip, continue |
| Alt exceeds limit | Generated text too long | Trim to max_chars at a word boundary |
Best Practices
- Lead the alt text with the concrete noun + distinguishing attribute ("Charcoal merino crew-neck sweater"), not marketing fluff — that's what agents match on.
- Keep
overwrite: falsefor the first pass to fix the worst gap (blanks) safely; do a reviewedoverwrite: truepass later for filename-style alts. - Don't keyword-stuff — one accurate sentence beats a comma salad and reads better for screen-reader users too.
- Re-run
shopify-admin-agentic-readiness-auditafterward to confirm the alt-text coverage pillar moved.
Signals
- GitHub stars
- 188
- Forks
- 19
- Last commit
- Aug 2026
ahel review
S4info
community integration — published by 40rty-ai, not shopify
Automated review, not a security audit. Ruleset v1.
Advanced
- Catalog kind
- skill
- Gateway key
shopify-admin-agentic-image-alt-text- Source
- github.com/40rty-ai/shopify-admin-skills