LosenAgent-readiness for commercial websites

All articles

The price has to be in the markup, not in a script

On 102 of 135 sites there was at least one category we could not assess at all — overwhelmingly product data, because none was machine-readable anywhere we could reach.

Published

An agent that is going to say "it costs 1,299 kroner and it is in stock" has to find those facts in the response the server sends. Not in something inserted afterwards, not in an image, and not only in a <span> a script fills in.

In our scan of 135 Norwegian sites, 102 sites had at least one category that could not be assessed at all. Overwhelmingly that was product data, for the simple reason that none was machine-readable anywhere we could reach. That is a measurement, not a gap in the tool: we checked four large retailers by hand, and platekompaniet.no and devold.com served zero JSON-LD on their own product pages — fetched straight from their own product sitemaps, 62 KB and 257 KB of HTML, without a single ld+json block. bohus.no and norli.no had none across 74 and 106 cached pages respectively.

Four things that break

The price is injected by a script. Then it is gone, even if you have JSON-LD alongside — because the JSON-LD is usually filled in by the same script.

The price is formatted the Norwegian way. "1 299,00" is right for a human and useless in a field meant to parse as a number. In schema.org/Offer, price must be 1299.00 with a full stop and no spaces, and priceCurrency must be NOK. The visible price on the page can and should read 1 299 kr. This is a specifically Nordic trap and an easy one to fall into.

Variants are missing. This is the largest gap we know of. We gave real shopping tasks to several assistants, and all of them broke at the same point: per-variant availability. The page says the jacket exists. It says nothing machine-readable about size L in black being sold out. The agent recommends an item the customer cannot buy, which is worse than no recommendation.

The data does not match the page. Google requires structured data to match visible content. We verify that data is readable, not that it is correct — but an Offer saying 999 where the page says 1,299 is a mistake that comes back to you one way or another.

How to check

Open a product page and look for the price the way a machine does:

curl -sL https://yourshop.no/a-product | grep -oE "1[ .]?299([,.][0-9]{2})?" | head
curl -sL https://yourshop.no/a-product | grep -o "ld+json" | wc -l

The first command must match. If it does not, the price is not in your response.

Then look at the block itself:

curl -sL https://yourshop.no/a-product \
  | sed -n 's/.*<script type="application\/ld+json">\(.*\)<\/script>.*/\1/p' | head -c 2000

Look for four things: "@type": "Product", an offers whose price is a bare numeric value, priceCurrency: "NOK", and availability. If price is empty or reads "1 299,00", you have found the fault.

One important exception, again

Structured data does not have to sit on the product page. kicks.no puts 61 marked-up products on every listing page, and that was more than enough for both ChatGPT and Claude to find a product and its price when we tested by hand. We first reported it as missing because we were looking in the wrong place. That was our bug, and we now count product data wherever the site actually publishes it.

So check your listing pages too, not only your product pages.

What to change

  1. Put price, currency and availability in the first response from the server. Both as visible text and in JSON-LD.
  2. Write price as a machine number. 1299.00, full stop, no thousands separator, priceCurrency: "NOK" beside it. Show 1 299 kr to the customer by all means.
  3. Mark up every variant. Use ProductGroup with hasVariant, and give each variant its own Offer with its own availability and its own sku. This is the single change with the highest return, because it is where every agent breaks.
  4. Give each variant its own address. ?variant=... as a real link, with the right price and availability in the response.
  5. Include gtin and brand when you have them. That is how an agent connects your item to what the customer actually asked for.

How to verify the fix

One command should be enough:

curl -sL https://yourshop.no/a-product | grep -A3 "availability"

You should see availability for the variant the address points at, and a price that is a number. Test a variant you know is sold out and check that the answer says OutOfStock. That is the one test that catches the failure every agent actually hit.

Where these numbers come from

102 of 135 comes from our own scan of 135 Norwegian sites in August 2026 (docs/findings.md). The checks on platekompaniet.no, devold.com, bohus.no and norli.no were done by hand on 8 August 2026, against the sites' own product sitemaps. The per-variant availability observation comes from giving several assistants real shopping tasks and recording where they broke.

We verify that data is readable. We do not verify that it is correct.

All articles · Scan a site