All posts
Ray Iyer
Ray Iyer
Co-founder, Anglera

Making your Shopify catalog agent-readable (AEO)

How to make a Shopify PDP agent-readable: structured attributes, Product JSON-LD, server-rendered specs, and clear answers AI agents can parse.

Making your Shopify catalog agent-readable (AEO)

Getting a Shopify product page in front of a shopping agent isn't a ranking problem — it's a parsing problem. ChatGPT, Perplexity, and Google's AI Mode don't browse a page the way a person does; they fetch HTML, look for schema.org markup, and read whatever text is already in the DOM. If your specs live only in an image, a hand-written paragraph, or a component that renders after a click, the agent either guesses or skips your product. This guide walks through the concrete, Shopify-specific steps to make a PDP something both buyers and agents can actually read.

Start with the HTML an agent actually sees, not the rendered page

Shopify's standard (non-headless) themes run on Liquid, which is processed server-side — the HTML that comes back from the first request already contains the rendered product section markup, prices, and metafield values. That's a real advantage for agent-readability: most AI crawlers and fetch-based agents don't execute JavaScript, so anything present in that initial response is visible to them by default.

Two things break this in practice:

  • Headless/composable storefronts (Hydrogen, or a custom React/Next.js front end on the Storefront API) can ship content that only appears after client-side hydration. If you've gone headless, confirm the product route is actually server-rendered (SSR) for the fields you care about — attributes, price, and availability — not populated by a useEffect after load.
  • Theme-side JS-only widgets. Accordions, tabs, and "load more specs" components built with client-side JavaScript can hide content from the initial HTML even in a stock Liquid theme, depending on how the theme (or an app block) implements them. The fix isn't to avoid interactive UI — it's to make sure the underlying text is server-rendered into the DOM and merely hidden with CSS (display: none / collapsed state), not injected by JS after the fact.

See Shopify's own architecture reference for how templates, sections, and snippets compose into the rendered page: Theme architecture.

Get the attributes into structured fields, not prose

An agent can extract "Material: Recycled aluminum" from a labeled field far more reliably than from a sentence buried in a paragraph. In Shopify this means metafields and metaobjects, not just the product description box.

  • Metafields attach a typed value (text, number, dimension, weight, rating, list, reference) to a namespace and key on a product, e.g. product.metafields.custom.material. Definitions are created in the admin under Settings, then Metafields and metaobjects, and in Online Store 2.0 themes they're exposed directly in the theme editor as dynamic sources — no code required to place them on the page. See Metafield Liquid object.
  • Metaobjects handle multi-field, repeatable structures — a spec table row, a "compatible with" list, or an FAQ entry with question/answer fields — and can be referenced from multiple products so one edit updates every page that uses it. See Metaobjects — Shopify Help Center.

A minimal FAQ metaobject in Liquid looks like this:

{% for block in product.metafields.custom.faqs.value %}
  <div class="faq-item">
    <h3>{{ block.question.value }}</h3>
    <div>{{ block.answer.value }}</div>
  </div>
{% endfor %}

The point isn't the exact markup — it's that "material," "compatible engines," "return window," and "how to size this" each live in a field an agent can key off of, and that field is rendered as plain HTML text on the page.

Emit Product JSON-LD — and know what it doesn't cover

Shopify ships a structured_data Liquid filter that turns a product object into schema.org JSON-LD automatically: a Product type when the product has no variants, or ProductGroup when it does. It's typically already wired into main-product.liquid in Online Store 2.0 themes. Documentation: Liquid filter: structured_data.

<script type="application/ld+json">
  {{ product | structured_data }}
</script>

This default output covers the basics — name, description, image, brand, price, currency, availability, and URL. It generally does not include everything Google (and increasingly AI answer engines) now expect for merchant listings: hasMerchantReturnPolicy, shippingDetails (OfferShippingDetails), aggregateRating, and review. Google's guidance on these is explicit and has been tightened over the past two update cycles — treat the default filter output as a floor, not a finished implementation, and extend the JSON-LD (via a custom snippet, or by overriding the block in main-product.liquid) with return-policy and shipping properties if you rely on them. See Google: Product structured data, Merchant return policy structured data, and Merchant shipping policy structured data.

For buyer-question content specifically, FAQPage schema is still valid schema.org markup and still useful signal for AI systems parsing a page, even though Google narrowed which sites get the visual FAQ rich-snippet in search results back in 2023 — don't expect the SERP treatment, but do expect the structured Q&A to help an agent match a shopper's question to your answer.

Don't forget bot access

None of the above matters if your robots.txt blocks the fetcher. Shopify's default robots.txt is generally permissive, but themes and apps sometimes add custom rules. Check that you aren't blocking answer-engine fetchers (e.g. OAI-SearchBot, ChatGPT-User, PerplexityBot, Claude-User) alongside the traditional Googlebot — this is a one-line audit worth doing before assuming a page isn't being read for a content reason.

What an agent can and cannot extract today

Can reliably extract: name, price, currency, availability, images, and any attribute exposed via structured_data or plain server-rendered HTML (metafields, metaobject-driven spec blocks, FAQ text in the DOM).

Cannot reliably extract: text baked into an image (a size chart as a JPEG), specs that only render after a client-side fetch or hydration step, values that exist only in an app's own iframe/widget without a server-rendered fallback, and anything omitted from both the visible page and the JSON-LD (e.g., a return window mentioned nowhere but a linked policy page).

How to validate

  • View rendered vs. raw HTML: load the PDP, then use "View Page Source" (not just DevTools' inspected DOM) to confirm attributes and JSON-LD are present in the actual server response, not only after JS runs.
  • curl the page with a plain user agent and grep for your key attributes and the application/ld+json block: a missing match there is a missing match for most agent fetchers too.
  • Google's Rich Results Test and the Schema Markup Validator to confirm your JSON-LD parses and which properties are detected.

Verified as of July 2026 against Shopify's structured_data filter and metafield/metaobject documentation and Google's current Product structured data guidance; field requirements for merchant listings are Google-side and can shift independently of Shopify's theme defaults, so re-check before a major catalog push.

Anglera doesn't touch any of this page-rendering layer — it's focused on the data one level down: keeping product attributes, specs, and use-case language complete and current in your PIM or metafields so there's something accurate to render in the first place. Once that data is in good shape, the structured_data filter, metafields, and metaobjects above are what carry it onto the page for buyers and agents alike.

Ray Iyer

About the author

Ray IyerCo-founder, Anglera

Ray is a co-founder of Anglera, building the product-data infrastructure for agentic commerce — turning messy catalogs into structured, AI-readable data that buyers and answer engines can find. Previously product at Uber; Stanford CS.

See it on your own SKUs.

A 30-minute walkthrough on your categories and your supplier data.

Book a demo