Diagnostic 2 stores checked Schema.org + Google docs verified August 2026

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.

Verdict

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.

Spec

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.

One product page, two versions of the price What a shopper sees $140 rendered text, for humans What a machine reads "price": 14000 "currency": "USD" structured data, no symbol Same product. A text search for "$140" never finds the machine price.
Two renderings of one price, from the same product page: the formatted string a shopper sees, and the symbol-free number a machine reads.
Evidence

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.

14000
Allbirds Tree Runners
machine price, USD, no symbol
$140
Allbirds Tree Runners
what a shopper sees
26
Gymshark shorts
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.

Diagnosis

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.00 or 14000 plus USD, 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 &#8377; 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.
Two ways a store-audit tool's text search misses a price that is fully machine-readable in structured data.
Two ways to check the same price THE AUDIT'S METHOD Search page text for "$140" No match found Flag: prices invisible (false positive) THE CHECK THAT WORKS Open view-source, read structured data price + priceCurrency present Machine-readable (correct)
The audit's text search and the actual check diverge at the same fork: which layer of the page gets read.
Fix

The check that is actually right, in 30 seconds

You do not need a tool for this. You need the page's source.

01
Open view-sourceOpen your product page, right-click, and choose View Page Source (Ctrl-U on Windows, Cmd-Option-U on a Mac). This is the raw HTML the server sent, before JavaScript runs, which is the honest test.
02
Search for pricePress Ctrl-F and search for price. Look for a block that contains both price and priceCurrency (or a currency field), usually inside a script tagged application/ld+json.
03
Read the resultIf you see something like "price": "140.00", "priceCurrency": "USD", your price is machine-readable. The audit that said otherwise was scanning the wrong layer.
04
Know the real red flagIf you search the whole source and find no price or currency field anywhere, that is a real problem: the price only exists after JavaScript runs. That is the exact case these audits are meant to catch, and the view-source check tells you the truth either way.
Stakes

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.

Underwing / Elytron Labs Diagnostic

Recommended reads

All articles →