All posts
Ray Iyer
Ray Iyer
Co-founder, Anglera

Making your Salesforce Commerce Cloud catalog agent-readable (AEO)

How to turn enriched Salesforce Commerce Cloud product data into Page Meta Tag Rules, Product JSON-LD, and server-rendered content AI agents can parse.

Making your Salesforce Commerce Cloud catalog agent-readable (AEO)

Salesforce Commerce Cloud (B2C Commerce) gives you two separate SEO systems out of the box — Page Meta Tag Rules for <title>/<meta> tags and URL Rules for clean paths — but it does not ship a native Product JSON-LD generator on SFRA or Composable Storefront (PWA Kit). That means the gap between "our PIM has rich, enriched product data" and "an AI shopping agent or answer engine can actually read it off the PDP" is a template-layer job you have to build deliberately. This guide covers what to configure in Business Manager, what to hand-code in ISML or React components, and how to check that a bot sees the same thing a human does.

What "agent-readable" actually requires

AI agents and answer engines (Google's AI Overviews, Perplexity, ChatGPT browsing, shopping-focused crawlers) generally rely on three signals, in rough order of trust:

  1. Structured data (JSON-LD Product, Offer, AggregateRating, BreadcrumbList) — machine-parseable and unambiguous.
  2. Server-rendered HTML — content present in the initial response body, not injected after JavaScript executes.
  3. Visible on-page copy that directly answers buyer questions (fit, compatibility, care, what's included).

Commerce Cloud can satisfy all three, but each one lives in a different part of the platform: JSON-LD is custom template code, meta tag content comes from Business Manager rules, and rendered HTML depends on whether you're on SFRA (always server-rendered) or Composable Storefront/PWA Kit (server-rendered on first load, then hydrated).

Step 1: Confirm the underlying attributes exist and are mapped

Before touching templates, make sure the catalog actually has what a Product schema needs: brand, GTIN/UPC/MPN, a normalized availability status, currency-qualified price, and — critically — the descriptive attributes that answer real buyer questions (material, dimensions, compatibility, use-case). These live as standard and custom attributes on your Product objects in Business Manager's Catalog, or are pushed in via the Product/Catalog import (XML) or the Product API. If those fields are sparse or inconsistent across your assortment, the templates below will just be rendering empty tags.

Step 2: Set Page Meta Tag Rules (title, description) in Business Manager

This is Commerce Cloud's native SEO layer, and it's the easiest win. In Business Manager, go to Merchant Tools > SEO > Page Meta Tag Rules, and define rules scoped to Product, Category/Search, or Content. Rules use static text mixed with dynamic expressions, evaluated per page, with inheritance flowing down from the root category so you don't have to author a rule per product:

${dw.system.Site.getCurrent().getName()} — ${Product.name} | ${Product.custom.materialType}

Rules support up to roughly 4,000 characters and resolve against objects like Product, Category, and Search. In ISML, use dw.web.PageMetaData and the isPageMetaTagSet() check as a fallback so a missing rule doesn't render a blank tag:

<isif condition="${!pdict.CurrentPageMetaData.isPageMetaTagSet('description')}">
    <meta name="description" content="${Resource.msg('global.default.description','locale',null)}" />
</isif>

If you're on a headless/Composable Storefront build, the Shopper Products API supports a page_meta_tags expansion on the products and product-search endpoints (added in a recent B2C Commerce API release) that returns this same rule-generated metadata alongside product data, so you don't need a second call to reconstruct it client-side. Confirm the expansion is present in your org's current API version before relying on it, since rollout can lag by instance.

Step 3: Add Product JSON-LD — this is the part SFCC doesn't give you

Neither SFRA nor PWA Kit auto-generates Product JSON-LD; you add it in the template layer. In SFRA, the natural place is a template included from htmlHead.isml on the Product-Show controller, built from the same pdict.product data already available to the page:

<script type="application/ld+json">
{
    "@context": "https://schema.org/",
    "@type": "Product",
    "name": "${product.productName}",
    "sku": "${product.id}",
    "gtin": "${product.custom.gtin}",
    "brand": {
        "@type": "Brand",
        "name": "${product.brand}"
    },
    "description": "${product.shortDescription}",
    "image": "${product.images.large[0].url}",
    "offers": {
        "@type": "Offer",
        "priceCurrency": "${product.price.currency}",
        "price": "${product.price.sales.value}",
        "availability": "${product.available ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock'}",
        "url": "${product.selectedProductUrl}"
    }
}
</script>

Two things worth flagging so this stays accurate rather than boilerplate: (1) attribute paths above (product.custom.gtin, product.brand, etc.) map to whatever your model actually populates — audit against your Product model before copy-pasting; (2) if you sell variants, use ProductGroup/variant Product markup per Google's variant guidance rather than one flat Product node, since a shopper or agent landing on a color/size variant needs its own price and availability. On Composable Storefront, the same JSON object is built server-side in the React component that renders the PDP (e.g., inside the SSR-rendered page shell) and injected via a <Helmet>/head-management pattern so it's present in the initial HTML response, not appended after hydration.

Step 4: Make sure it's actually server-rendered, not client-only

SFRA templates are rendered server-side by definition, so this step is mostly a Composable Storefront/PWA Kit concern. PWA Kit's Managed Runtime runs an Express render function per request and can cache the rendered output at the CDN edge — crawlers and agent fetchers get the same HTML a browser gets on first paint. The risk is when JSON-LD or key descriptive copy is built from state that only resolves client-side (e.g., a useEffect call to a personalization service) — that content simply won't exist in the response body a non-JS-executing agent fetches. Keep the product identity data (name, brand, GTIN, price, availability, core attributes) in server-rendered props; reserve client-only rendering for genuinely personalized or frequently-changing elements.

What an AI agent can and cannot extract

Can extract reliably: product name, brand, price/currency, in-stock status, and any attribute you explicitly put into JSON-LD or into server-rendered visible copy (materials, dimensions, compatibility statements, what's-in-the-box).

Cannot extract: content injected only after client-side hydration or behind a "load more specs" interaction with no server-rendered fallback; attributes that exist in your PIM/catalog but were never mapped into either the JSON-LD block or the visible PDP copy; anything requiring inference (e.g., "works with X" compatibility that's implied by category placement but never stated in text).

How to validate

  • View rendered vs. raw source: curl -s https://yoursite.com/product-page | grep -A 40 'application/ld+json' — if the block is missing from curl output but visible in the browser DOM inspector, it's client-injected and agents relying on raw fetches will miss it.
  • Rich Results Test: run the live PDP URL through Google's Rich Results Test to confirm the Product type parses and flag missing required fields (price, availability, condition for merchant listing eligibility).
  • Schema Markup Validator: cross-check with Schema.org's validator for spec compliance independent of Google-specific requirements.
  • Spot-check a sample across categories, not just one hero product — meta tag rule inheritance and attribute completeness both tend to degrade in long-tail categories.

Verified as of July 2026 against Salesforce Help and Salesforce Developers documentation for B2C Commerce Page Meta Tag Rules, SFRA/ISML rendering, PWA Kit rendering, and current Google Search Central structured-data guidance; menu paths and field names are current for standard B2C Commerce Business Manager but can shift slightly by release and by whether you're on SFRA or Composable Storefront.

None of this works if the attributes feeding these templates are thin or inconsistent, which is the part Anglera is built for: it continuously enriches your catalog's specs, identifiers, and use-case attributes directly in the PIM or commerce platform you already run, so the JSON-LD and meta-tag work above has genuinely rich, complete data to render. Your PIM stores the data; Anglera does the work of keeping it complete — this page-side implementation is what turns that completeness into something buyers and agents can actually read.

Sources

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