An AI shopping agent never reads your WooCommerce product page the way a shopper does — it assembles a structured record of your product from three separate sources (the JSON-LD schema in your HTML, your merchant feed, and the crawled page text), then ranks that record against a query. The uncomfortable part: WooCommerce's default Product JSON-LD emits only name, price, availability and SKU, leaving brand, GTIN, MPN, shipping and return fields empty — so the record the agent builds is missing exactly the fields it compares products on.
We build an AI-visibility plugin for WooCommerce, and the single most common misread we see is store owners optimising the page — better photos, richer copy, a persuasive layout — when the agent that decides whether they get recommended never looks at any of it. It reads fields. This article walks through what an agent does with those fields, so you can see your catalog the way an agent does: as rows of data, most of them blank.
What does an AI shopping agent actually read from a WooCommerce product?
It reads structured fields first, prose last, and it reads them from three representations of the same product that often disagree. The three are: the Schema.org Product markup embedded as JSON-LD in your page, the feed you send to Google Merchant Center (or Meta, or an agent-facing endpoint), and the rendered HTML text. Agents lean hardest on the structured two because a field labelled gtin is unambiguous, whereas the same number buried in a paragraph has to be guessed at and verified.
This is why "agents read schema, not homepages" is true but incomplete. The agent isn't choosing between your schema and your page — it's merging all three into one candidate record and scoring it on completeness and internal consistency. A fact that appears in one representation and contradicts another is worse than a fact that's simply missing, because a contradiction lowers the agent's confidence in the whole record. WooCommerce stores are unusually prone to this precisely because those three copies are generated by different systems: core outputs the JSON-LD, a feed plugin builds the feed, and your theme renders the page.
What happens when an agent runs a real query against your store?
Every product gets eliminated the moment it hits a query gate it has no data for — so the way to understand which fields matter is to follow one query through the agent. Take a shopper asking their assistant for "waterproof women's hiking boots, size 8, under $150, in stock and delivered by the weekend." That single sentence is really six filters, applied in sequence, and your product either carries the field each one needs or it drops out silently:
- "hiking boots" → the agent needs your product category / MPN to place you in the right taxonomy. No category, and the query never reaches you.
- "waterproof" and "size 8" → these are attributes. If they live in your description prose instead of structured attribute fields, the agent may never extract them, and you fail a spec filter you'd actually pass.
- "under $150" → the agent reads
price+priceCurrency. A price range from a variable product, or a currency it can't confirm, and you're dropped from the budget filter. - "in stock" →
availability. Blank or contradictory, and many agents treat you as unavailable and skip you entirely. - "delivered by the weekend" → the agent estimates delivery from weight and dimensions. No shipping data, no place in the delivery-time comparison.
Clear six gates and you're a candidate. Then comes the field that decides whether you win: GTIN. It's the join key that lets the agent recognise your boots and three competitors' listings as the identical physical product, so it can aggregate reviews and rank you on price. Without it, you're an island — the agent can't prove you're the same item anyone else sells, so it can't confidently prefer you. WooCommerce only added a native GTIN field in 2024, which is why most catalogs built before then fail this last gate on every SKU.
That query used six of the fields; here's the full map, so you can check your own catalog field by field against what each one actually unlocks:
| Field | What the agent does with it | What happens when it's blank |
|---|---|---|
| GTIN / EAN / UPC | Matches your product to the identical item across retailers; aggregates reviews and prices | Can't be compared or price-ranked against competitors selling the same item |
| Brand | Disambiguates near-identical products; answers brand-named queries | Excluded from every query that names a brand |
| Price + priceCurrency | Filters against the shopper's budget and "under $X" limits | Dropped from any budget-bounded query |
| Availability | Decides whether you're shown at all | Often treated as unavailable and skipped |
| Weight + dimensions | Estimates delivered cost and "ships to me by date" answers | Absent from delivery-time and total-cost comparisons |
| Attributes (size, colour, material) as fields | Spec-matching for "waterproof", "size 8", "cotton" queries | Attribute must be guessed from prose — usually isn't, so you lose the match |
| MPN + product category | Places the item in the right taxonomy so the query reaches it | Miscategorised or unranked |
| Image URL | Renders the product as a visual candidate in the answer | No thumbnail, lower click intent |
Why does a fully-detailed product page still lose?
Because the agent scores your structured data, not your sentences — and a fact stated only in prose isn't a field it counts on. Here's what WooCommerce actually hands an agent for a typical product, straight out of the box:
{
"@type": "Product",
"name": "Trailhead Waterproof Hiking Boot",
"sku": "TH-884",
"offers": {
"@type": "Offer",
"price": "139.00",
"priceCurrency": "USD",
"availability": "InStock"
}
}
Everything the shopper asked for that isn't in that block — brand, GTIN, the waterproof attribute, the size, the weight for delivery — is invisible, even if your page shouts all of it in bold. The agent doesn't guess when a field is empty; it moves to a competitor whose record answers the question. This is the confidence-hierarchy trap, and it's the opposite of how humans read: a person trusts the sentence, an agent trusts the field. It gets worse with the several AI crawlers that still don't execute JavaScript — any attribute your theme renders client-side isn't just low-confidence, it's absent before extraction even begins. The fix is never better copy; it's moving each fact out of a sentence and into the WooCommerce field built for it.
Why do your three copies of the same product disagree?
They disagree because WooCommerce, your feed plugin and your theme each generate product data independently, and nothing forces them to match. The failure we see most is price: a sale price the theme renders live, a JSON-LD offers block still caching last week's number, and a feed that syncs on its own schedule. To an agent merging all three, that's one product making three claims — and a product that contradicts itself on price is one the agent has reason to distrust and drop from a price-sensitive comparison.
Variable products are where this turns ugly, and it's the WooCommerce-specific failure most guides skip. A variable product often exposes a price range instead of a single price, per-variation GTINs nobody ever filled in, and stock that varies per variation but collapses to one value in the schema. Ask an agent for "the blue pair in size 8 under $140" and it needs that variation's own price, GTIN and availability — if your markup only carries the parent's range, the agent can't confirm the specific variation qualifies, so it passes on you. Reconciling this by hand across a few hundred SKUs is the kind of task nobody finishes, which is exactly the gap Contexta's commerce readiness audit closes: it checks every product for the fields agents actually need — image, price, GTIN, brand, weight — and drops you a per-product fix link, turning an impossible manual sweep into a worklist. It's the groundwork that has to exist before any UCP or ACP checkout plugin can transact your catalog at all.
What should you fix first on a WooCommerce store?
Fix the join keys and offer fields first — GTIN, brand, price, availability — because those decide whether your product enters a comparison at all; everything else refines a product the agent has already accepted. The honest order, highest leverage down:
- Backfill GTIN/EAN on every product that has one, and explicitly flag genuinely identifier-less items (handmade, custom, own-brand) rather than leaving the field ambiguous.
- Reconcile price and availability across page, JSON-LD and feed so all three agree — a contradiction here is a silent disqualifier on Shopping surfaces today.
- Promote attributes from prose to fields — size, colour, material, waterproofing — so spec-filtered queries can actually match you.
- Confirm the data renders without JavaScript, because the crawlers that build the record frequently don't run it.
None of this touches your page design, which is precisely why it gets skipped — and precisely why the stores that do it quietly win. When an agent surfaces five products for a query, it's choosing among records, and the most complete, most consistent record tends to take the sale no matter whose homepage is prettier. If you want to know which agents are already sending you shoppers before you invest the hours, tracking AI referral traffic shows you where to aim first. But the sequence never changes: an agent buys from data, so fix the data first.
FAQ
Do AI shopping agents read my product page or my structured data?
They read your structured data first and your page text last, then merge both into a single product record. A fact stated only in your description prose is a low-confidence source an agent may not extract, while a fact in a JSON-LD field or feed attribute is unambiguous. If the field is blank, the agent doesn't guess — it moves to a competitor whose record answers the query.
Why does WooCommerce product schema fail AI shopping agents by default?
WooCommerce's default Product JSON-LD emits only name, price, availability and SKU, leaving brand, GTIN, MPN, shipping and return fields empty. Those empty fields are exactly the ones agents use to match, filter and compare products, so the record an agent builds of your product is missing its most decisive data. WooCommerce only added a native GTIN field in 2024, so older catalogs usually have it blank on every SKU.
Which single product field matters most to AI shopping agents?
GTIN is the highest-leverage field because it's the join key that lets an agent recognise your listing and a competitor's as the same physical product. Without it, an agent can't aggregate reviews or price-rank you against identical items, which removes you from any comparison query. Backfilling GTIN across the catalog is usually the first fix worth making.
Why do agents skip products where the info is clearly on the page?
Because agents score structured fields, not sentences, and several AI crawlers don't execute the JavaScript that renders some page content. An attribute written in your description prose — or shown only after a script runs — often never reaches the agent's record. Moving the fact into the WooCommerce field built for it is what makes the agent see it.
