Module reference

Rich Data for Magento 2 — module reference

Covers angeo/module-rich-data 2.0.0 · Checked 16 October 2026 · MIT licensed

Rich Data adds structured data (JSON-LD) to your Magento 2 pages. It writes one linked @graph per page, so ChatGPT, Gemini, Perplexity and Google read your catalog as connected data, not as loose pieces.

Every node has a stable @id. For example, offers.seller points to the same Organization on every page, instead of repeating a name.

Schema it adds

SchemaPagesMain fields
ProductProduct pagesname, description, image, sku, gtin/mpn, brand, offers, aggregateRating
ProductGroupConfigurable productshasVariant, variesBy, productGroupID, an offer per variant
OrganizationAll pagesname, description, url, logo, sameAs, contactPoint
WebSiteHomepagename, url, publisher
BreadcrumbListProduct, category, CMS pagesfull trail
CollectionPageCategory pagesItemList of the products on the current page
FAQPageCMS pages you choosequestion and answer pairs

Prices follow the store’s tax display setting, so the price in the markup matches the price on the page. Configurable, grouped and bundle products publish an AggregateOffer with lowPrice and highPrice.

What it fixes in AEO Audit

SignalBeforeAfter
Product schemaFail / warnPass
Merchant policiesFailPass, once you turn it on and fill it in
Product ratingWarnPass, when reviews exist
JSON-LD quality — breadcrumbsWarnPass
FAQPage schemaWarnPass, on the pages you choose

Requirements

Magento2.4.x (Open Source, Mage-OS or Adobe Commerce) — magento/framework >=103.0.0
PHP8.2 – 8.5 — ~8.2.0||~8.3.0||~8.4.0||~8.5.0

Installation

composer require angeo/module-rich-data
bin/magento module:enable Angeo_RichData
bin/magento setup:upgrade
bin/magento setup:di:compile                # production mode only
bin/magento cache:flush

Coming from 1.x? Read UPGRADE.md in the repository first. The markup shape changes, and prices become tax-inclusive on stores that show prices with VAT.

Example output

{
  "@context": "https://schema.org",
  "@graph": [
    { "@type": "Organization", "@id": "https://shop.example/#organization", "name": "Example Store" },
    {
      "@type": "Product",
      "@id": "https://shop.example/alpine-jacket.html#product",
      "name": "Alpine Jacket",
      "offers": {
        "@type": "Offer",
        "price": "121.00",
        "priceCurrency": "EUR",
        "availability": "https://schema.org/InStock",
        "seller": { "@type": "Organization", "@id": "https://shop.example/#organization" }
      }
    },
    { "@type": "BreadcrumbList", "@id": "https://shop.example/alpine-jacket.html#breadcrumb" }
  ]
}

Prefer one script tag per schema, as in 1.x? Set General → Output mode to One script tag per schema.

Setting it up

  1. Open Stores → Configuration → Angeo → Rich Data (JSON-LD).
  2. In Organization schema, add a one- or two-sentence description, a logo URL (512×512 PNG works well) and your social profile URLs. AI engines use this as the summary of your brand.
  3. In Product schema, turn on Include Brand and choose the attribute. If you have barcodes, turn on GTIN / MPN and choose those attributes too.
  4. Only when your real return window, shipping cost and delivery times are known, turn on Merchant policies. The default country is US — change it to the countries you ship to.
  5. For FAQ pages, list the CMS page identifiers. Empty means any identifier that contains “faq”.
  6. Check the result with the CLI command below.

Wrong policy values can hurt your eligibility in Google and ChatGPT Shopping. Leave Merchant policies off until the values are true.

FAQ markup on CMS pages

Data attributes are the reliable way:

<div data-faq-question="What is your return policy?"
     data-faq-answer="We offer 30-day returns on all items in original condition.">
</div>

Without them, the module looks for an <h2> or <h3> followed by a <p>. The homepage is never treated as an FAQ page.

Google shows FAQ rich results only for government and health sites. Treat FAQPage as content for AI answer engines, not as a Google feature.

Checking the output

bin/magento angeo:rich-data:validate --store=default
bin/magento angeo:rich-data:validate --store=default --product-id=42
bin/magento angeo:rich-data:validate --category-id=11
bin/magento angeo:rich-data:validate --cms-identifier=faq
bin/magento angeo:rich-data:validate --json | jq .
CommandWhat it does
bin/magento angeo:rich-data:validateValidate the JSON-LD output for a product, category or CMS page.

The exit code is non-zero when a node has no @id, an offer is incomplete, or two nodes collide. You can use it in CI.

Configuration reference

All settings are under Stores → Configuration → Angeo → Rich Data (JSON-LD). The table shows each field, its config path (for bin/magento config:set) and its default value.

General (2)
SettingConfig pathDefault
Enabledangeo_rich_data/general/enabledYes
Output modeangeo_rich_data/general/output_modegraph
Product schema (15)
SettingConfig pathDefault
Enabledangeo_rich_data/product/enabledYes
Include AggregateRatingangeo_rich_data/product/include_aggregate_ratingYes
Include SKUangeo_rich_data/product/include_skuYes
Include Brandangeo_rich_data/product/include_brandNo
Brand attribute codeangeo_rich_data/product/brand_attributemanufacturer
Item conditionangeo_rich_data/product/conditionNewCondition
Include GTIN / MPN identifiersangeo_rich_data/product/include_identifiersNo
GTIN attribute codeangeo_rich_data/product/gtin_attribute—
MPN attribute codeangeo_rich_data/product/mpn_attribute—
Publish configurable products as ProductGroupangeo_rich_data/product/include_variantsYes
Maximum variants per productangeo_rich_data/product/max_variants20
priceValidUntil window (days)angeo_rich_data/product/price_valid_days365
In-stock availability URLangeo_rich_data/product/availability_in_stockhttps://schema.org/InStock
Out-of-stock availability URLangeo_rich_data/product/availability_out_of_stockhttps://schema.org/OutOfStock
Include BreadcrumbList (deprecated)angeo_rich_data/product/include_breadcrumbYes
Breadcrumb schema (1)
SettingConfig pathDefault
Enabledangeo_rich_data/breadcrumb/enabledYes
Merchant policies (return and shipping) (11)
SettingConfig pathDefault
Enable return policyangeo_rich_data/merchant_policies/return_enabledNo
Return window (days)angeo_rich_data/merchant_policies/return_days30
Applicable countryangeo_rich_data/merchant_policies/return_countryUS
Return feeangeo_rich_data/merchant_policies/return_feeFreeReturn
Enable shipping detailsangeo_rich_data/merchant_policies/shipping_enabledNo
Flat shipping rateangeo_rich_data/merchant_policies/shipping_rate0
Shipping destination countryangeo_rich_data/merchant_policies/shipping_countryUS
Handling time, min daysangeo_rich_data/merchant_policies/handling_days_min—
Handling time, max daysangeo_rich_data/merchant_policies/handling_days_max—
Transit time, min daysangeo_rich_data/merchant_policies/transit_days_min—
Transit time, max daysangeo_rich_data/merchant_policies/transit_days_max—
Organization schema (7)
SettingConfig pathDefault
Enabledangeo_rich_data/organization/enabledYes
Organization nameangeo_rich_data/organization/name—
Organization descriptionangeo_rich_data/organization/description—
Logo URLangeo_rich_data/organization/logo—
sameAs URLsangeo_rich_data/organization/same_as—
Contact telephoneangeo_rich_data/organization/contact_telephone—
Contact typeangeo_rich_data/organization/contact_typecustomer service
WebSite schema (2)
SettingConfig pathDefault
Enabledangeo_rich_data/website/enabledYes
Include SearchActionangeo_rich_data/website/include_searchactionNo
CollectionPage schema (categories) (1)
SettingConfig pathDefault
Enabledangeo_rich_data/collection_page/enabledYes
FAQPage schema (2)
SettingConfig pathDefault
Enabledangeo_rich_data/faq/enabledYes
CMS page identifiersangeo_rich_data/faq/cms_identifiers—

Notes on a few settings:

  • WebSite → SearchAction is off by default. Google removed the sitelinks search box in November 2024, so it gives no Google feature. It stays for other consumers.
  • CollectionPage follows paging and sort order. It does not reflect layered navigation filters, because they are not ready when the page head renders.

Adding your own schema

Implement Angeo\RichData\Api\Data\SchemaInterface and register the builder:

<type name="Angeo\RichData\Model\JsonLd\Renderer\SchemaRenderer">
    <arguments>
        <argument name="builders" xsi:type="array">
            <item name="my_schema" xsi:type="object">Vendor\Module\Model\JsonLd\Builder\MySchemaBuilder</item>
        </argument>
    </arguments>
</type>

Give your root node an @id and it joins the graph like the built-in schemas.

FAQ

Will it clash with my theme’s JSON-LD?

It can, if your theme or another module also prints Product or Organization schema. Run the validate command and the AEO Audit JSON-LD quality check. Remove the duplicate source you do not need.

Why are merchant policies off by default?

Because wrong values can hurt your eligibility. Turn them on only when your return window, shipping cost and delivery times are correct.

Does it support configurable products?

Yes. They are published as ProductGroup with one offer per variant, up to the variant limit you set (hard limit 50).

Does it work with Hyvä?

Yes. The suite modules support Hyvä, and JSON-LD is printed in the page head.

Why do my prices include tax in the markup?

Prices follow the store’s tax display setting, so the markup matches the price a shopper sees. Since 2.0.0 that means tax-inclusive prices on stores that display VAT.

This page was written from the README.md, composer.json and etc/*.xml files of tag 2.0.0, read on 16 October 2026. Settings, commands and defaults come straight from that code. If a newer release is out, the README on GitHub wins.