Your AI-Visibility Audit Says Your Price Is Invisible. It Almost Certainly Isn't.
I checked what an audit tool actually searches for versus what a machine actually reads, and found the two are not the same layer of the page.
If an AI-visibility audit told you your product prices are "invisible without JavaScript" or "hidden from AI shoppers," the verdict is probably wrong. A shopper and a machine read two different versions of the same price on the same page. A shopper sees "$140." A machine reads a plain number, 140.00 or 14000, with the currency named separately as USD, stripped of the dollar sign on purpose. An audit that scans your page's visible text looking for the string "$140" will not find that string, and will report the price as missing, even when the real, machine-readable price is sitting right there in your structured data. The 30-second check that is actually correct is at the bottom of this piece.
What a machine actually reads for price
Product prices are published to machines through structured data, and the vocabulary for it, schema.org/Offer, is explicit about the format. The price is a number, and the currency is a separate field. From the schema.org guidance on the price property:
Use the priceCurrency property (with standard formats: ISO 4217 currency format, e.g. "USD") instead of including ambiguous symbols such as '$' in the value. Use '.' (Unicode 'FULL STOP' (U+002E)) rather than ',' to indicate a decimal point.
Read that again, because it is the whole point: the spec tells you to keep symbols like "$" out of the price value. Google follows the same rule. Its merchant listing structured data documentation defines price as "the current, active offer price of a product. Follow the schema.org usage guidelines," and priceCurrency as "the currency used to describe the product price, in three-letter ISO 4217 format." Google adds that Product markup "can be eligible for display in merchant listing experiences on Google Search." In other words, the symbol-free number in your structured data is the version a product-search system reads. The "$140" a person sees is a rendering of it, for people.
I pulled two live stores to see it
I fetched the raw server HTML of two well-known product pages, before any JavaScript runs, and looked at how each carries the price.
machine price, USD, no symbol
what a shopper sees
Offer price, structured data
On the Allbirds Tree Runners page the machine-readable price in the served HTML is "price":14000 with "currency":"USD", integer cents, no dollar sign, currency named separately, while the page shows shoppers "$140." On the Gymshark shorts page the structured product data carries "@type":"Offer" with "price":26. Two different stores, same pattern: the price a machine can read is present in the server response, and it does not look like the price a person sees.
One honest caveat from doing this by hand: where exactly the structured price lives varies by store and theme. Sometimes it is inside a <script type="application/ld+json"> block, sometimes in another data layer the theme emits. What is consistent is the representation. The machine price is a bare number plus a currency code, not a formatted string with a symbol.
Why the audit misfires
Many store-audit tools fetch a page and search the visible text for a formatted price string. That method produces a false "invisible" flag in at least two ways.
How the false flag happens
- Format mismatch. The structured price is
140.00or14000plusUSD, not$140.00. A literal search for "$140" does not match it. The spec told the store to leave the symbol out, then the audit went looking for the symbol. - Encoded symbols. Currency symbols are sometimes written in the HTML source as character entities rather than the character itself. The Rupee sign, Unicode U+20B9, can appear as
₹instead of the glyph. A byte-for-byte search for "₹1,299" then fails even though the price renders perfectly in the browser. This one depends on the theme, so it is not universal, but I have seen it produce a scary audit number on a store whose price was completely fine.
What's actually true
- The audit is checking the layer built for human eyes.
- It then concludes the machine cannot read a price.
- Google's own documentation says it reads the structured data.
- So does any tool that bothers to look there.
The check that is actually right, in 30 seconds
You do not need a tool for this. You need the page's source.
price. Look for a block that contains both price and priceCurrency (or a currency field), usually inside a script tagged application/ld+json."price": "140.00", "priceCurrency": "USD", your price is machine-readable. The audit that said otherwise was scanning the wrong layer.What is actually a red flag, and what isn't
Before you pay anyone to "fix" a hidden price, spend the 30 seconds. A genuine red flag looks like this: no structured price in the source at all, or a feed price that disagrees with the page price (I wrote about that failure mode last week), or a page whose body is empty until scripts run. A symbol-free number with a separate currency code is not a red flag. It is the format the spec asked for.
I run Elytron Labs, and the reason I keep writing these is that the scary number in a store audit is often a measurement error, not a store error. When Pollen checks a store it reads the structured data the way a machine does, not the rendered pixels a person sees, so a symbol-free price does not get miscounted as a missing one. If you want to see what your own structured data actually says, the free scan at pollen.elytron.in reads the same layer this post just asked you to open by hand.
Your price is not invisible. It is formatted for a reader you haven't checked yet.