A founder-voice guide to the on-page signals Perplexity Shopping pulls into product cards, why JavaScript-locked prices kill citations, and the fastest fixes.

If you have a premium Shopify product page that ranks well on Google and still gets ignored by Perplexity when a buyer asks for it by category, the gap is on-page mechanics. Perplexity does not run on backlinks or domain authority. It pulls live structured data from the product page itself, and pages that hide price, availability, or description behind JavaScript usually do not make the response.
Perplexity Shopping pulls product cards from pages that ship four signals cleanly. The first is Schema.org Product structured data in JSON-LD with name, image, brand, and description. The second is a Schema.org Offer nested inside that Product with price, priceCurrency, and availability. The third is a 2 to 3 sentence direct description in the first paragraph of the body, not buried under marketing copy. The fourth is a canonical URL that points to a stable, indexable product page. Pages missing any of these usually do not appear as a product card.
The retrieve-vs-cite asymmetry matters here too. A Search Engine Land study found that only 15% of pages ChatGPT retrieves end up in the cited answer, and Perplexity behaves similarly. The model fetches a lot of pages, then a second pass picks which ones to surface. The second pass strongly favors pages with clean, extractable structured data.
The single most common reason a premium DTC product page gets ignored is the price. Specifically, the price that lives in a React state hook, gets rendered to the DOM after hydration, and never makes it into the static HTML the AI fetch reads.
When Perplexity fetches a product page, it gets the server-rendered HTML. If the price is "$" or "Loading..." in the static HTML and gets replaced by "$249" client-side, the model sees "$" and either skips the page or surfaces it without a price. A buyer asking "what does this product cost" gets a useless answer.
The fix is mechanical. Put the default price for the master variant in the JSON-LD Schema.org Offer in the page head, server-rendered. Use priceSpecification blocks to express variant pricing rather than swapping prices in JavaScript-only state. The page can still update the visible price client-side; the structured data stays correct from the first byte.
Signal one: Product schema. A JSON-LD block in the page head with @type: Product, name, image, brand, description, sku, and at least one Offer. The image URL must be absolute, not relative. The description should match the visible page description, not be a separate marketing pitch.
Signal two: Offer schema. Nested inside Product, with price, priceCurrency, availability, and url. Price is a number, not a string with currency symbols. Availability is one of the standard Schema.org enums (InStock, OutOfStock, PreOrder). Url is the canonical product URL.
Signal three: Direct first paragraph. The first 2 to 3 sentences of the body should describe the product in the words a buyer would search for. "What is this." "Why is it different." Not "Welcome to our collection of..." or a brand origin story. The model extracts these sentences for the product card.
Signal four: Canonical URL. A <link rel="canonical"> tag in the head pointing to the indexable product page with a trailing slash. If the same product is reachable from /products/sku-123, /collections/all/products/sku-123, and a tag page that lists it, Perplexity needs the canonical to know which one to cite.
These four are the floor. Brands shipping all four get retrieved consistently. Brands missing two or more usually do not.
A few patterns that show up on premium DTC pages and do nothing for Perplexity Shopping:
Unlike ChatGPT Shopping, Perplexity does not currently require a merchant file upload to surface products in shopping responses. The retrieval is page-driven. That makes the on-page signals more important, not less, because there is no feed-side fallback.
It also means the on-page work transfers between assistants. The same Schema.org Product markup that helps a brand show up in Perplexity also helps with ChatGPT Shopping retrieval and Claude product mentions. Brands building for AI shopping should treat on-page schema as table stakes and feeds as the next layer up.
If your product pages ship most of the schema but Perplexity is still skipping you, walk this checklist on the worst-converting PDP first.
Test the page with curl. curl -A "Mozilla/5.0 ..." https://your-store.com/products/sku-123/ and grep for application/ld+json. If the price in the JSON-LD is missing or shows as 0, the JavaScript-locked price problem is your gap. Fix that first.
Validate the Schema. Use Google's Rich Results Test on the URL. Confirm Product, Offer, and AggregateRating come back without errors. Errors here mean Perplexity is also missing them.
Check the canonical. View source and look for <link rel="canonical" href="..." />. The href should point to the product URL with a trailing slash and no query strings. If the canonical points to a category page or a different domain, fix that.
Rewrite the first paragraph. Open the body with a 2 to 3 sentence direct description that names what the product is and why a buyer would want it. Move the brand origin story below.
These four checks fix most invisible-to-Perplexity cases. They take less than a day for a single product, longer to roll across the catalog.
The on-page work for Perplexity overlaps almost entirely with the on-page work for ChatGPT Shopping. How ChatGPT Shopping actually picks products covers the broader signal set including third-party reviews and merchant feed submission. The difference between an SEO product feed and an agent-readable one covers what to ship beyond the page when you want to be more than retrievable.
The thread across all three articles is the same. The page is being read by a machine. The machine extracts what is in the structured data and the first paragraph of the body. Hide either one and the buyer asking the assistant about your category gets a competitor.