Your Shopify Schema Is There, But AI Crawlers Can't See It (The JavaScript Trap)
Your product page looks complete. Open it in a browser, run a schema validator, and the structured data is right there: price, availability, ratings, all of it. So you assume AI shopping engines can read it. Many of them cannot.
There is a gap between what your browser shows and what a crawler sees, and structured data falls straight into it more often than any other signal. If your JSON-LD is injected by JavaScript after the page loads, a crawler that does not run that JavaScript sees a product page with no structured data at all. The validator passes. The crawler still skips you.
This is the single most common reason a store with "good schema" still does not surface in AI search. Here is why it happens, and a check you can run in under a minute.
What you'll learn
- What JavaScript-injected structured data is, and why it looks fine to you but missing to a crawler
- Why many AI crawlers do not run JavaScript, so injected schema never reaches them
- A 60-second View Page Source check to see whether your schema is actually crawler-visible
- Where injected schema usually comes from, and how to get it server-rendered instead
- How crawler-visible schema maps to your Schema sub-score and overall AI Visibility Score
What JavaScript-injected schema actually means#
A web page arrives in two stages. First the server sends raw HTML. Then the browser runs any JavaScript on the page, which can add, change, or remove content after the fact. What you see on screen is the result of both stages combined.
Structured data can live in either stage. Server-rendered JSON-LD is written into the raw HTML before it ever reaches the browser. JavaScript-injected JSON-LD is not in that raw HTML at all; a script adds it a moment after the page loads. On screen the two look identical. To anything that reads only the raw HTML and does not run the JavaScript, they are completely different. One is present. The other does not exist.
This is not a Shopify-specific flaw. It is how a lot of apps and themes add schema: a review app injects its rating markup, a theme adds Product schema through a script, a third-party widget writes its own JSON-LD on load. Each one works perfectly for a human visitor and can be invisible to a crawler.
Why AI crawlers fall into the gap#
Rendering JavaScript is expensive. Running the full browser engine on every page, for every crawl, across the whole web, costs orders of magnitude more time and compute than just reading the HTML the server sends. So many crawlers do not do it, or do it selectively, or do it on a delay.
Search engines have spent years building the infrastructure to render JavaScript at scale, and even they do it as a deferred second pass, not on first read. The newer wave of AI crawlers does not all have that infrastructure, and the ones fetching a page live in the middle of a user's conversation have no time budget for a render step at all. They take the raw HTML and move on. If your structured data was not in that HTML, it was not read.
The result is a page that passes every check a human can run and still presents as data-less to the exact engines you are trying to reach. Your price, your availability, your ratings, your GTIN, all of it can be sitting in a script that the crawler never executes.
The 60-second check for crawler-visible schema#
You can find out which stage your structured data lives in without any tool. The trick is to look at the raw HTML, not the rendered page.
Open one of your product pages. Right-click and choose View Page Source. This matters: View Page Source shows the raw HTML the server sent, which is what a crawler reads. Do not use Inspect or Inspect Element, because that shows the page after JavaScript has run, which hides the entire problem.
In the source view, use your browser's find function and search for application/ld+json. Then look at what you find.
If you find it and the block contains your actual product price and availability, your JSON-LD is server-rendered and in the raw HTML where crawlers can read it. Good.
If you do not find application/ld+json at all, or you find the tag but it is empty, or your price and availability only appear when you use Inspect and not in View Page Source, your structured data is being injected by JavaScript. To the crawlers that do not render, it is not there.
Run this on a few different product types, not just one. It is common for a store to server-render some schema and inject the rest, so a single page is not a verdict for the whole catalog.
What to do if you fail the check#
The fix is to get your Product schema into the server-rendered HTML instead of injecting it on load. How you do that depends on where the schema is coming from, and that is the part most merchants cannot see on their own.
If the markup is added by your theme, the fix lives in the theme's Liquid templates, where JSON-LD can be written server-side. If it is added by an app, the app's rendering method is the question, and some apps offer a server-side mode while others do not. If a review or ratings widget is injecting its own markup, that specific block may be invisible even when the rest of your schema is fine, which is why ratings so often fail to appear in AI results while everything else looks healthy.
The diagnosis has to come before the fix. You need to know which blocks are server-rendered, which are injected, and which engines that affects, before you change anything. Guessing leads to editing the wrong template or disabling the wrong app.
Where this fits in your AI visibility#
Bot access decides whether a crawler can reach your store. Structured data decides whether it can understand what it reached. The JavaScript trap sits inside that second layer: you can have perfect crawler access and genuinely good schema, and still fail, because the schema is in a stage the crawler never sees.
In ShelfScore this is part of your Schema sub-score. The audit reads your pages the way a crawler does, from the raw HTML, so it flags structured data that is present to a human but missing to a machine, names which blocks are affected, and tells you how many points clean, server-rendered schema would recover. Each fix is labeled Up to +N pts recoverable so you know its ceiling before you touch it.
Frequently asked questions#
My schema validator says my structured data is valid. Why would a crawler miss it? Most validators render the page the way a browser does, running the JavaScript first, so they see injected schema as present. A crawler that reads only the raw HTML does not run that JavaScript and sees nothing. A passing validator confirms your schema is well-formed; it does not confirm the schema is in the raw HTML where a non-rendering crawler can read it. View Page Source is the check that answers that.
What is the difference between View Page Source and Inspect? View Page Source shows the raw HTML the server sent, before any JavaScript runs. That is what a non-rendering crawler reads. Inspect, or Inspect Element, shows the live page after JavaScript has modified it, which includes anything injected on load. Because Inspect hides the exact problem, always use View Page Source to check for crawler-visible structured data.
Does Google see my JavaScript-injected schema? Google renders JavaScript, but as a deferred second pass rather than on first read, so injected schema can be picked up later rather than immediately. The newer AI crawlers do not all render JavaScript, and live user-triggered fetches generally do not render at all. Server-rendering your schema removes the dependency entirely and makes the data readable on first pass by every engine.
Why do my product details show but my reviews and ratings do not? Review and ratings widgets very commonly inject their markup with JavaScript after the page loads, even when the rest of your Product schema is server-rendered. The product fields are in the raw HTML; the ratings block is added later by the widget and is invisible to a non-rendering crawler. This is why ratings are one of the most frequent things to go missing in AI results.
If I move my schema to server-rendered, how fast will AI engines see it? There is no guaranteed timeline; it depends on how often each engine recrawls your store. The controllable part is making sure that when the next crawl happens, the structured data is in the raw HTML on first read. Server-rendering removes the render-dependency that was causing the miss, so the next crawl is the one that counts.
How do I check my whole catalog at once instead of one page at a time? ShelfScore reads your store the way a crawler does and flags structured data that is present to a browser but missing from the raw HTML, across your product pages, then ranks the fix by how many points it recovers. The audit starts in under 60 seconds, and the free tier shows your composite AI Visibility Score and your top fixes.
Sources#
- OpenAI crawler documentation. Roles of GPTBot (training), OAI-SearchBot (ChatGPT Search), and ChatGPT-User (live user-initiated fetch); live fetches operate without a rendering step.
- Google Search Central documentation on JavaScript SEO. Google processes JavaScript in a deferred second wave of indexing rather than on initial crawl.
- Schema.org and Google structured data guidelines. JSON-LD is the recommended format for product structured data and must be present in the served markup to be reliably read.
Run a free ShelfScore audit
See your AI Visibility Score across Bot Access, Schema, and Data in under 60 seconds. No credit card.
Install Free on Shopify