I checked a store that was doing everything right and ChatGPT still couldn't see it

A store owner asked me to look at why they weren’t showing up in AI answers. Good store, real products, clean SEO, ranking fine on Google. Their assumption was that they needed better content.

That wasn’t it. Their product price and description only existed after JavaScript ran. Google renders JS so Google was happy. Several AI fetchers don’t, so what those got back was a page with a title and almost nothing else. Months of content work sitting behind a door that half the assistants couldn’t open.

They had no way of knowing. There’s no error, no warning, no line in any report. Everything looked fine from inside the admin.

Two other things I keep finding, in case they save someone the same month I nearly cost that owner:

Shipping and returns pages matter more than anyone expects. Assistants read them heavily, because someone asked “will this get here by Friday” and the assistant has to answer that before it will name your store. Vague delivery info means it can’t answer, so it names someone else. That page you wrote in ten minutes two years ago is doing your closing argument.

And none of this shows up as traffic. AI assistants reading your store don’t announce themselves, and the humans they send over usually land in Direct with no referrer. So the whole thing happens next to your analytics rather than in it.

If you want to check the JS one yourself, it takes a minute. Open a product page, view source, search for your price. If it’s not in there, some assistants aren’t seeing it either.

Happy to look at anyone else’s store the same way if you post a URL. Disclosure: I build a tool in this space, and this particular check needs nothing installed, which is why I’m offering it.

One extra check: do not only search source for the visible price. Shopify may include it in product JSON-LD even when the page body is JS-driven.

  • In View Source, search for application/ld+json, then confirm name, description, price, currency, availability, SKU, and product URL are present.
  • Turn off JavaScript in Chrome DevTools and reload the product page. The title, main description, price, variant status, and buy link should still be understandable.
  • Rewrite shipping copy with actual regions, processing time, delivery ranges, cutoff times, and return window. Avoid vague wording like usually ships quickly.
  • Check robots.txt and CDN/firewall logs to make sure AI crawlers are not blocked or challenged.

I’d also repeat this on one product from each template, since theme sections and app-built pages can behave differently.

I scan small Shopify stores for exactly this daily (I build in this space, so grain of salt) and I want to add a base rate, because the JS case is real but on stock themes it is less common than this thread might suggest. Liquid themes render product pages server side, and most current themes ship price and availability in Product JSON-LD, so the initial HTML usually carries the essentials before any script runs. Where I actually see the door closed is headless builds and product pages assembled by page builder apps. The distinction matters because an owner on a standard theme could burn a weekend hunting for a rendering problem they do not have.

What turns up far more often is quieter: the store is perfectly fetchable and there is just not much to read. Of the six stores I scanned this morning, all six were serving only the default agent instructions file at llms.txt, which tells an assistant how to complete a checkout but nothing about what the store sells or who it is for. Thin product descriptions, under roughly 80 words, ranged from 10 to 45 out of 50 products checked per store. An assistant can open every one of those pages cleanly and still have nothing to work with.

Strong second on shipping and returns pages. They answer the questions people actually ask an assistant, like whether it will arrive by Friday and what happens if it does not fit. Vague “ships fast” copy gives the model nothing to commit to, while concrete regions, cutoff times and return windows start showing up in answers almost immediately.

Crawlight — When a Shopify store has clean JSON-LD schema but remains “invisible to ChatGPT / Perplexity AI shopping agents,” the issue almost always traces back to media asset ingestion and JS-rendered variant Offer blocks.

Three specific technical blind spots that break AI agent product discovery:

  1. Silent WebP Binary Dropping: LLM vision models and AI search crawlers parse product feeds directly from your Shopify CDN. If your product catalog was imported via CSV referencing raw supplier .webp URLs, Shopify’s background importer often quietly drops the image binary. The JSON-LD schema renders text fine, but AI vision models see blank media slots, severing the visual entity indexing path.

  2. Variant-Level Offer-to-Image Mismatch: AI shopping agents index variant-specific offers (e.g., “Medium / Navy Blue”). If the CSV’s ‘Variant Image’ column is left blank on secondary size rows under the assumption that Shopify auto-inherits the color image, AI crawlers fail to bind the variant Offer entity to the visual asset.

  3. Server-Side Rendered (SSR) Alt Text Attributes: Ensure variant image ALT tags are embedded directly in static HTML rather than populated via client-side JavaScript theme swatches, as headless AI crawlers don’t execute heavy JS bundles.

If you want to sanitize supplier WebP images and auto-map variant image ALT metadata locally before import, consider using EasyCatch (a client-side Chrome extension). Its Local Canvas Transpiler converts supplier WebP images to static JPGs inside your Chrome sandbox and outputs Matrixify-compliant ZIPs with pre-mapped variant rows in 1 click — ensuring 100% media asset survival for AI search indexing. 100% Local-First.

You’re right and I overstated it. Stock Liquid themes server-render and most ship price and availability in Product JSON-LD, so the essentials are usually there before any script runs. The cases I’ve actually hit were page builder pages and one headless build, which is exactly the split you’re describing, and I wrote it as if it were the common case.

Your llms.txt number is the more interesting thing in that reply though. Six out of six serving only the default file matches what I’d expect but I haven’t scanned at that volume. Shopify started serving it natively earlier this year, so most owners have one and don’t know it exists. Do you see owners fix it once they’re told, or does it just sit there because nobody owns that file?

Thin descriptions at 10 to 45 out of 50 is a brutal spread. Were the stores at the high end running supplier copy?

Fair, “can’t see it” was too strong. It’s a signal, not proof. ChatGPT-User renders JavaScript, several others don’t, so the honest version is that missing data in source means some assistants are working with less, not that all of them are blind.

Same on the Direct point, and that one’s worth saying plainly since I wrote it loosely. Direct is where things land for a dozen reasons and you can’t read an AI share out of it. That’s the problem rather than the measurement.

Your three-way test is better than my one-liner, especially disabling JS instead of just reading source.

The per-template point is the one I’d have missed. App-built product pages behave nothing like the theme default, and people test one product and assume the whole catalogue.

Also right that JSON-LD can carry the price even when the body is JS-driven, which is part of why my source check was too blunt.

Thanks Steve. The source versus rendered check is cheap enough that it’s worth doing before any content work, which is mostly why I posted it.

The “if Google can see it, everything can” assumption is the one that gets people, and it used to be a safe assumption. Worth adding what a couple of others corrected me on above though: on a stock Liquid theme the essentials are usually in the initial HTML anyway, so this bites page builder pages and headless builds more than the average store.

Agreed that no crawl tool really covers the AI fetchers yet. Most of them are checking what a search engine would see, which is a different question from what an assistant gets when it fetches your page mid-answer.

Out of interest, has SiteGuru or anything else you use ever surfaced which agents actually hit the site, or is it all page-side checks? That’s the gap I keep running into.

Do you have a source on the WebP binary dropping during CSV import? I’ve not run into that one and I’d want to read up before passing it on to anyone.

@Crawlight — Great question. The distinction is between Shopify’s CSV syntax parser (which accepts WebP string syntax during initial upload) and the background CDN ingestion worker (which handles the actual binary fetch).

You can self-reproduce this silent failure mode in 3 minutes without complex dev tools:

  1. Test Setup: Take a supplier product CSV (e.g. from 1688/Alibaba) containing 20+ variant rows where ‘Image Src’ or ‘Variant Image’ columns reference raw .webp endpoints with dynamic CDN query parameters (e.g. ?v=123 or cropping parameters).

  2. The Import Illusion: Run Shopify’s native CSV import. The admin UI status screen will report “20 Products Successfully Imported” with zero error logs because the text CSV schema itself is valid.

  3. The Silent Drop: Inspect the live storefront product page 5 minutes later. You’ll observe that while text attributes (title, price, options) imported fine, 30-50% of variant image slots render as blank media containers.

Why it happens: Shopify’s background worker queues image fetching asynchronously after the text CSV import completes. When supplier CDNs enforce hotlink protection, strict SSL handshakes, or dynamic query-string parameters, Shopify’s worker hits a timeout or handshake failure and skips the binary fetch quietly — rather than rolling back the product text import or throwing an admin error.

Pre-transpiling supplier WebP files to static .jpg binaries locally in the browser sandbox before generating the CSV eliminates those background worker handshake timeouts completely. That’s why local pre-conversion guarantees 100% variant image survival.