<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ievgenii Gryshkun</title>
    <description>The latest articles on DEV Community by Ievgenii Gryshkun (@angeo).</description>
    <link>https://dev.to/angeo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3580569%2F169d293e-1a42-4bef-b904-4e3aaaca6513.jpeg</url>
      <title>DEV Community: Ievgenii Gryshkun</title>
      <link>https://dev.to/angeo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/angeo"/>
    <language>en</language>
    <item>
      <title>Magento AI Brand Visibility: Does ChatGPT Recommend Your Store?</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Sat, 13 Jun 2026 07:17:29 +0000</pubDate>
      <link>https://dev.to/angeo/magento-ai-brand-visibility-does-chatgpt-recommend-your-store-4j10</link>
      <guid>https://dev.to/angeo/magento-ai-brand-visibility-does-chatgpt-recommend-your-store-4j10</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; set &lt;code&gt;published: true&lt;/code&gt; when you're ready. The &lt;code&gt;canonical_url&lt;/code&gt; above tells Google the original lives on angeo.dev, so this cross-post won't compete with it. Replace &lt;code&gt;cover_image&lt;/code&gt; with the uploaded featured image URL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; when your customers ask ChatGPT, Claude or Perplexity &lt;em&gt;"where should I buy this?"&lt;/em&gt;, you currently have no idea whether your store appears in the reply. &lt;a href="https://github.com/angeo-dev/module-aeo-brand-visibility" rel="noopener noreferrer"&gt;Angeo AEO Brand Visibility&lt;/a&gt; is a free, open-source &lt;strong&gt;Magento 2&lt;/strong&gt; module that measures exactly that: it runs brand-probing prompts across the five major AI models and scores your real-world &lt;strong&gt;AI brand visibility&lt;/strong&gt; from 0 to 100.&lt;/p&gt;

&lt;p&gt;Search no longer means only Google. More buying research now starts inside an AI assistant that returns one synthesized answer naming a few stores. &lt;strong&gt;AI Engine Optimization (AEO)&lt;/strong&gt; is the work of making sure your brand is one of those names — and this module tells you, in minutes, whether it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI brand visibility matters for Magento merchants
&lt;/h2&gt;

&lt;p&gt;AI answers are &lt;em&gt;winner-takes-most&lt;/em&gt;. Where a search results page lists ten links, an AI assistant usually names two or three stores. If you're not in that shortlist, you're invisible to that buyer — there is no "page two". Traditional SEO tools can't see this: they measure rankings, backlinks and crawl health, not what a model actually &lt;em&gt;says&lt;/em&gt; when prompted. That blind spot is what AEO Brand Visibility closes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Magento AI brand visibility tracking works
&lt;/h2&gt;

&lt;p&gt;You set your brand name, domain, category and a few top products. The module sends natural shopping prompts — &lt;em&gt;"What are the best online stores to buy {category}?"&lt;/em&gt;, &lt;em&gt;"Tell me about {brand}"&lt;/em&gt;, &lt;em&gt;"Compare {brand} with similar stores"&lt;/em&gt; — to every enabled AI provider. Each response is analysed for five signals, scored, cached and saved to a history log so you can watch the trend over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supported AI providers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Why it's included&lt;/th&gt;
&lt;th&gt;Free tier?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;ChatGPT&lt;/strong&gt; (OpenAI)&lt;/td&gt;
&lt;td&gt;The most-used assistant; the default benchmark for AI recall.&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Claude&lt;/strong&gt; (Anthropic)&lt;/td&gt;
&lt;td&gt;Strong reasoning; common for research-style queries.&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Perplexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Live web search — best signal for what the internet says about you now.&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Gemini&lt;/strong&gt; (Google)&lt;/td&gt;
&lt;td&gt;Tied into Google's ecosystem; generous free tier.&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Groq&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast, free Llama hosting — ideal for zero-cost testing.&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Start with the free providers (Gemini and Groq) to validate your setup at zero cost, then add paid providers for the most commercially relevant picture.&lt;/p&gt;

&lt;h3&gt;
  
  
  The five visibility signals
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mentioned&lt;/strong&gt; — your brand or a configured alias appears anywhere in the answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt; — the model actively suggests you (recommendation language near your mention, or you appear in a ranked list).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL cited&lt;/strong&gt; — your domain is referenced in the response, the strongest trust signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First result&lt;/strong&gt; — you appear in the first quarter of the answer, i.e. top-of-mind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Positive sentiment&lt;/strong&gt; — favourable language sits close to your mention.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each signal is weighted and combined into a single &lt;strong&gt;0–100 score&lt;/strong&gt; with an A–F grade.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get in the Magento admin
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run Audit&lt;/strong&gt; — one click queries every enabled model and shows live scores, per-provider chips and signal rates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Statistics &amp;amp; trend chart&lt;/strong&gt; — average, best and worst scores plus a score-over-time graph from your fresh (non-cached) runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit History&lt;/strong&gt; — your recent runs, each expandable to the full prompt-by-prompt detail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action Plan&lt;/strong&gt; — a prioritised, time-bounded roadmap of what to fix first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single Query Tester&lt;/strong&gt; — send one prompt to one provider and inspect the raw response.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Automate it: CLI, cron and CI gates
&lt;/h2&gt;

&lt;p&gt;AI brand visibility drifts as content, reviews and the web change, so the module ships a CLI command and a cron job — and it can fail a CI build if your score drops below a threshold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run a full audit across all enabled providers&lt;/span&gt;
bin/magento angeo:aeo:brand-visibility

&lt;span class="c"&gt;# Force fresh queries (bypass the cache)&lt;/span&gt;
bin/magento angeo:aeo:brand-visibility &lt;span class="nt"&gt;--refresh&lt;/span&gt;

&lt;span class="c"&gt;# Test a single provider / prompt&lt;/span&gt;
bin/magento angeo:aeo:brand-visibility &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;perplexity &lt;span class="nt"&gt;--prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;brand_direct

&lt;span class="c"&gt;# Machine-readable output for dashboards&lt;/span&gt;
bin/magento angeo:aeo:brand-visibility &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json

&lt;span class="c"&gt;# Gate a pipeline: exit 1 if the score falls below 60&lt;/span&gt;
bin/magento angeo:aeo:brand-visibility &lt;span class="nt"&gt;--fail-on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Built to extend angeo/module-aeo-audit
&lt;/h2&gt;

&lt;p&gt;AEO Brand Visibility plugs into &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;angeo/module-aeo-audit&lt;/a&gt; as a live-signal checker, sitting alongside the 15 built-in technical checks (robots.txt, llms.txt, structured data and more). Your brand-recall score becomes part of the same unified AEO report — one command, one dashboard, technical and real-world signals together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security &amp;amp; privacy
&lt;/h2&gt;

&lt;p&gt;Provider API keys are stored with Magento's encrypted backend model and never written to logs. Outbound calls are HTTPS-only and don't follow redirects, admin endpoints are protected by ACL and form keys, and all AI-provider text is escaped before rendering. Serialization uses Magento's &lt;code&gt;SerializerInterface&lt;/code&gt; throughout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-aeo-brand-visibility
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;strong&gt;Stores → Configuration → Angeo AEO → Brand Visibility&lt;/strong&gt;, add at least one provider API key, set your brand name and domain, and hit &lt;strong&gt;Run Audit&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to improve your AI brand visibility score
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low mention rate?&lt;/strong&gt; Publish an &lt;code&gt;llms.txt&lt;/code&gt; file (&lt;a href="https://packagist.org/packages/angeo/module-llms-txt" rel="noopener noreferrer"&gt;angeo/module-llms-txt&lt;/a&gt;) and keep your store name consistent across every page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain not cited?&lt;/strong&gt; Strengthen backlinks and reference your canonical URL in structured data and &lt;code&gt;llms.txt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not being recommended?&lt;/strong&gt; Improve product content quality and implement review schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Appearing late in answers?&lt;/strong&gt; Build topical authority with category-focused content.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is the module free?&lt;/strong&gt; Yes — MIT licensed. You only pay for the AI provider usage you choose, and you can run it entirely free using the Gemini and Groq free tiers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which AI models does it check?&lt;/strong&gt; ChatGPT, Claude, Perplexity, Gemini and Groq. Enable any combination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will audits cost a lot in API fees?&lt;/strong&gt; Not if configured sensibly. Results are cached, you control how many prompts run, and total queries equal enabled providers × active prompts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Magento versions are supported?&lt;/strong&gt; 2.4.6, 2.4.7 and 2.4.8 (Adobe Commerce and Mage-OS), PHP 8.2–8.4. Requires &lt;code&gt;angeo/module-aeo-audit&lt;/code&gt; v3.0+.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is this different from SEO tools?&lt;/strong&gt; SEO tools measure rankings and crawlability. This measures what AI assistants actually say when asked shopping questions.&lt;/p&gt;




&lt;p&gt;AI assistants are already recommending stores in your category — the only question is whether they're recommending &lt;em&gt;you&lt;/em&gt;. Install &lt;a href="https://github.com/angeo-dev/module-aeo-brand-visibility" rel="noopener noreferrer"&gt;angeo/module-aeo-brand-visibility&lt;/a&gt;, run your first audit, and find out in minutes. You can also &lt;a href="https://angeo.dev/ai-magento-audit/" rel="noopener noreferrer"&gt;run a free 30-second AEO audit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://angeo.dev/magento-2-ai-brand-visibility/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>ai</category>
      <category>seo</category>
      <category>php</category>
    </item>
    <item>
      <title>The 4-Layer Magento 2 AEO Stack: Making Your Store Visible to ChatGPT, Claude &amp; Gemini (2026)</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Sat, 06 Jun 2026 19:06:09 +0000</pubDate>
      <link>https://dev.to/angeo/the-4-layer-magento-2-aeo-stack-making-your-store-visible-to-chatgpt-claude-gemini-2026-bjd</link>
      <guid>https://dev.to/angeo/the-4-layer-magento-2-aeo-stack-making-your-store-visible-to-chatgpt-claude-gemini-2026-bjd</guid>
      <description>&lt;p&gt;I've written here before about &lt;a href="https://dev.to/angeo/how-to-fix-robotstxt-for-chatgpt-and-gemini-in-magento-2-4e11"&gt;fixing robots.txt for the AI bots&lt;/a&gt; and &lt;a href="https://dev.to/angeo/how-to-check-if-your-magento-store-is-visible-to-chatgpt-free-aeo-audit-module-4hkm"&gt;checking your store's ChatGPT visibility with a free audit module&lt;/a&gt;. This post zooms out and puts the whole thing in one place: the four layers that decide whether an AI assistant can find, trust, and recommend your Magento store — and the honest data on which layers actually matter in 2026.&lt;/p&gt;

&lt;p&gt;Default Magento 2 typically scores around &lt;strong&gt;23% on an AEO audit&lt;/strong&gt; across the stores I've measured. Not because anything is broken — because every one of these signals ships off by default and nobody flipped them on.&lt;/p&gt;

&lt;p&gt;Here's the stack, in priority order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1 — robots.txt: you're probably blocking the bots you want
&lt;/h2&gt;

&lt;p&gt;The most common failure, and almost always accidental. A &lt;code&gt;robots.txt&lt;/code&gt; written for Google in 2019 says nothing about the AI fleet, and some security/hardening configs block &lt;em&gt;unknown&lt;/em&gt; bots — which now includes the crawlers feeding ChatGPT, Claude, Gemini, and Perplexity.&lt;/p&gt;

&lt;p&gt;There's no single user-agent to allow. In 2026 you're dealing with ~10 distinct AI bots across four platform families. Minimal explicit allow-list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User-agent: GPTBot
Allow: /

User-agent: OAI-SearchBot
Allow: /

User-agent: ChatGPT-User
Allow: /

User-agent: ClaudeBot
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: Google-Extended
Allow: /

Sitemap: https://yourstore.com/sitemap.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key gotcha: &lt;strong&gt;&lt;code&gt;Google-Extended&lt;/code&gt; is not &lt;code&gt;Googlebot&lt;/code&gt;.&lt;/strong&gt; Blocking it doesn't touch your Google ranking — it only governs whether Google's AI products may use your content. Tons of sites blocked it during the 2023–24 anti-scraper panic and never revisited. If you want AI visibility, reconsider it.&lt;/p&gt;

&lt;p&gt;Highest-leverage 20 minutes in the whole stack. Do it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2 — JSON-LD: Magento ships the wrong format and skips the one field that matters
&lt;/h2&gt;

&lt;p&gt;This one is Magento-specific and it's the difference between being eligible for AI Shopping answers and being silently dropped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Default Magento 2 outputs product structured data as microdata, not JSON-LD.&lt;/strong&gt; AI extraction systems strongly prefer JSON-LD — a clean, self-contained block they can parse without reconstructing meaning from scattered HTML attributes.&lt;/p&gt;

&lt;p&gt;And the field that quietly kills you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;offers.availability&lt;/code&gt; is frequently missing — and ChatGPT Shopping will skip a product with no availability signal entirely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From the model's side, it's assembling a &lt;em&gt;purchasable&lt;/em&gt; recommendation. A product it can't confirm is in stock is a liability, so it drops it. No warning. You just don't appear.&lt;/p&gt;

&lt;p&gt;Correct, AI-friendly block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@context&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://schema.org/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Product&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pre-Seasoned Cast Iron Skillet 12&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sku&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CAST-SKILLET-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;brand&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Brand&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YourBrand&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Offer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://yourstore.com/cast-iron-skillet-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;priceCurrency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;59.00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;availability&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://schema.org/InStock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;itemCondition&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://schema.org/NewCondition&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aggregateRating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AggregateRating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ratingValue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4.7&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reviewCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;212&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three traps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't inject schema via GTM.&lt;/strong&gt; AI crawlers generally don't execute JavaScript, so tag-manager-injected schema is invisible to them even though it validates in DevTools. It must be server-rendered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyvä themes ship with &lt;em&gt;zero&lt;/em&gt; product schema by default&lt;/strong&gt; — neither microdata nor JSON-LD. If you migrated to Hyvä for speed, you may have silently dropped your structured data. Check now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bind &lt;code&gt;availability&lt;/code&gt; to real stock&lt;/strong&gt;, never a hardcoded &lt;code&gt;InStock&lt;/code&gt;. A model that recommends your out-of-stock item once learns to distrust your feed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify it's in the raw HTML (no JS):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/your-product | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A30&lt;/span&gt; &lt;span class="s1"&gt;'application/ld+json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing returned = the AI layer sees nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3 — llms.txt: ship it, but not for the reason you've been sold
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is a Markdown file at your root giving AI systems a curated map of your store — to LLMs what robots.txt is to crawlers, but editorial rather than access-control.&lt;/p&gt;

&lt;p&gt;Now the honest part. &lt;strong&gt;The "llms.txt boosts your AI rankings" pitch isn't supported by 2026 data:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A 300k-domain study found ~&lt;strong&gt;10% adoption&lt;/strong&gt;; among the 50 most AI-cited domains, only &lt;strong&gt;one&lt;/strong&gt; had the file.&lt;/li&gt;
&lt;li&gt;One vendor logged 62,100 AI bot visits over 90 days — &lt;strong&gt;84 hit &lt;code&gt;llms.txt&lt;/code&gt;. That's 0.1%.&lt;/strong&gt; Another tracking 500M+ bot events found GPTBot, ClaudeBot, PerplexityBot, OAI-SearchBot and Google-Extended overwhelmingly skip it and crawl HTML directly.&lt;/li&gt;
&lt;li&gt;OpenAI, Anthropic, and Perplexity haven't committed to reading it automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So why ship it? Because it's a &lt;strong&gt;Business-to-Agent (B2A) play, not an SEO play.&lt;/strong&gt; Agentic and IDE-style tooling already fetches it, agentic commerce is heading the same way, and conventions like this often get published before platforms formally commit (robots.txt predated official search-engine support). It's half a day of cheap insurance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# YourStore&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Premium cast iron and carbon steel cookware. EU-based, ships across Europe,&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; 30-day returns, mid-range pricing.&lt;/span&gt;

&lt;span class="gu"&gt;## Categories&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Cast Iron Skillets&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://yourstore.com/cast-iron&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Dutch Ovens&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://yourstore.com/dutch-ovens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="gu"&gt;## Buying Guides&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Cast iron vs carbon steel&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://yourstore.com/guides/cast-vs-carbon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="gu"&gt;## Policies&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Shipping &amp;amp; Returns&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://yourstore.com/shipping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ship it, spend the half day, then &lt;strong&gt;stop optimizing it&lt;/strong&gt; and put your energy into Layers 1, 2, and 4. And remember: a stale &lt;code&gt;llms.txt&lt;/code&gt; is worse than none — wrong stock claims train models to distrust you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 4 — ACP &amp;amp; UCP: the part that's actually about money
&lt;/h2&gt;

&lt;p&gt;The 2026 shift bigger than schema tweaks: AI is moving from &lt;em&gt;discovery&lt;/em&gt; ("here are some pans") to &lt;em&gt;transaction&lt;/em&gt; ("I bought the pan for you"). Two protocols define that layer, and Magento merchants — unlike Shopify merchants — wire it up themselves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ACP (OpenAI + Stripe)&lt;/strong&gt; — live in ChatGPT since late 2025; settled into a discovery-and-feed role. You submit a spec-compliant feed, ChatGPT surfaces products, checkout uses delegated single-use payment tokens, with a transaction fee on completed Instant Checkout orders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UCP (Google + Shopify + 20-plus partners incl. Walmart, Target, Visa, Mastercard)&lt;/strong&gt; — announced at NRF Jan 2026, expanded at Google Marketing Live in May. Broader, protocol-agnostic (REST, MCP, A2A), spanning discovery → cart → checkout → post-purchase across Google AI Mode, Gemini, YouTube, Gmail. Agents discover capabilities via &lt;code&gt;/.well-known/ucp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reality check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's not "pick one."&lt;/strong&gt; They target different agent ecosystems; dual-protocol merchants reportedly see meaningfully more agentic traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most groundwork is shared&lt;/strong&gt; — clean schema, an accurate live feed, defined shipping/return/pricing policies are prerequisites for both and survive any spec reshuffle (ACP already pivoted away from native checkout once).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sensible Magento order:&lt;/strong&gt; solid Layers 1–3 → ship ACP feed → prepare UCP manifest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Shopify gets much of this by partnership default. Magento/Adobe Commerce: you own the stack — full control, full responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR priority order
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fix &lt;code&gt;robots.txt&lt;/code&gt; so the AI fleet can crawl you. (~20 min, highest leverage)&lt;/li&gt;
&lt;li&gt;Emit server-rendered JSON-LD with a &lt;strong&gt;live&lt;/strong&gt; &lt;code&gt;offers.availability&lt;/code&gt;. (Hyvä users: confirm you have &lt;em&gt;any&lt;/em&gt; schema.)&lt;/li&gt;
&lt;li&gt;Verify with no-JS &lt;code&gt;curl&lt;/code&gt;. Not in raw HTML = invisible.&lt;/li&gt;
&lt;li&gt;Ship &lt;code&gt;llms.txt&lt;/code&gt; as cheap B2A insurance, then leave it.&lt;/li&gt;
&lt;li&gt;Build the shared commerce substrate, attach ACP, then UCP.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Google decides whether you &lt;em&gt;rank&lt;/em&gt;. AI engines increasingly decide whether you &lt;em&gt;exist&lt;/em&gt; in the answer. Two separate jobs now.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The open-source modules behind this (AEO audit CLI, llms.txt generator, multi-store AI description tooling) are on &lt;a href="https://packagist.org/packages/angeo/" rel="noopener noreferrer"&gt;Packagist&lt;/a&gt; and documented at &lt;a href="https://angeo.dev" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;. The llms.txt and ACP/UCP figures come from independent 2026 studies — verify current spec versions as you implement, this area moves monthly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you've pulled your own AI-bot server logs on a Magento store, drop the numbers in the comments — real crawler data is still scarce and I'd like to compare.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>aeo</category>
      <category>chatgpt</category>
      <category>opensource</category>
    </item>
    <item>
      <title>llms.txt for Magento 2: Free vs Paid Modules (2026 Review)</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Mon, 01 Jun 2026 07:06:32 +0000</pubDate>
      <link>https://dev.to/angeo/llmstxt-for-magento-2-free-vs-paid-modules-2026-review-308l</link>
      <guid>https://dev.to/angeo/llmstxt-for-magento-2-free-vs-paid-modules-2026-review-308l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a cross-post. The original — with the full module-by-module comparison table, feature breakdown, and FAQ — is on &lt;a href="https://angeo.dev/llms-txt-magento-2-free-vs-paid-module-comparison/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;AI systems are increasingly shaping how users discover products.&lt;/p&gt;

&lt;p&gt;Instead of browsing category pages, users now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"best hiking boots under €150"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and get a synthesized answer immediately.&lt;/p&gt;

&lt;p&gt;This shift creates a new problem for eCommerce: your store content is no longer consumed only as HTML. &lt;code&gt;llms.txt&lt;/code&gt; is an attempt to provide AI systems with a cleaner, structured summary of a website.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multiple Magento 2 llms.txt solutions exist (free and paid)&lt;/li&gt;
&lt;li&gt;Differences are mostly about workflow, not output quality&lt;/li&gt;
&lt;li&gt;There is &lt;strong&gt;no confirmed evidence&lt;/strong&gt; that llms.txt impacts search rankings&lt;/li&gt;
&lt;li&gt;Value comes from better AI interpretation of store structure&lt;/li&gt;
&lt;li&gt;JSONL-style structured feeds may become more important long-term&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Modern LLM-based assistants compress pages, reconstruct product context, and may misinterpret or ignore important catalog structure.&lt;/p&gt;

&lt;p&gt;This can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;outdated product descriptions in AI answers&lt;/li&gt;
&lt;li&gt;missing categories&lt;/li&gt;
&lt;li&gt;incorrect pricing context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; tries to reduce that ambiguity by providing a simplified representation of the store.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is llms.txt?
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;llms.txt&lt;/code&gt; file is a Markdown-based endpoint typically located at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourstore.com/llms.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;store overview&lt;/li&gt;
&lt;li&gt;category links&lt;/li&gt;
&lt;li&gt;product references&lt;/li&gt;
&lt;li&gt;policies and informational pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not a formal standard and is still evolving.&lt;/p&gt;




&lt;h2&gt;
  
  
  llms.txt vs sitemap.xml vs robots.txt
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Consumers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;robots.txt&lt;/td&gt;
&lt;td&gt;crawler rules&lt;/td&gt;
&lt;td&gt;search engines, bots&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemap.xml&lt;/td&gt;
&lt;td&gt;URL discovery&lt;/td&gt;
&lt;td&gt;search engines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llms.txt&lt;/td&gt;
&lt;td&gt;content summary&lt;/td&gt;
&lt;td&gt;AI systems (varies)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are complementary layers, not replacements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Does it improve SEO?
&lt;/h2&gt;

&lt;p&gt;There is no verified evidence that &lt;code&gt;llms.txt&lt;/code&gt; directly influences Google rankings.&lt;/p&gt;

&lt;p&gt;Its impact is more likely indirect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clearer AI summaries&lt;/li&gt;
&lt;li&gt;more consistent product descriptions in LLM outputs&lt;/li&gt;
&lt;li&gt;reduced hallucination risk in catalog interpretation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Magento 2 implementation approaches
&lt;/h2&gt;

&lt;p&gt;In practice, implementations fall into three categories.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Manual file (small stores)
&lt;/h3&gt;

&lt;p&gt;Simple Markdown file maintained by hand. Works well when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;catalog changes rarely&lt;/li&gt;
&lt;li&gt;under 50–100 products&lt;/li&gt;
&lt;li&gt;no automation required&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Admin-driven modules (business teams)
&lt;/h3&gt;

&lt;p&gt;Paid extensions usually add an admin UI, content selection controls, scheduling (cron), and multi-store support. Useful when marketing teams manage content directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Developer / automation-driven modules
&lt;/h3&gt;

&lt;p&gt;Open-source or CLI-based tools typically provide CLI generation, cron updates, and JSONL output in some cases. This approach fits dynamic catalogs better.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the full feature-by-feature comparison of specific paid and free modules (Magedelight, Webkul, Plumrocket, Eleventex, Magefan, and the open-source option), see the &lt;a href="https://angeo.dev/llms-txt-magento-2-free-vs-paid-module-comparison/" rel="noopener noreferrer"&gt;complete comparison table on angeo.dev&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Example structure
&lt;/h2&gt;

&lt;p&gt;A typical &lt;code&gt;llms.txt&lt;/code&gt; might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Store Name&lt;/span&gt;

&lt;span class="gu"&gt;## Categories&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Hiking: https://store.com/hiking
&lt;span class="p"&gt;-&lt;/span&gt; Climbing: https://store.com/climbing

&lt;span class="gu"&gt;## Featured Products&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Trail Boot X3 — €149 — waterproof hiking boot
&lt;span class="p"&gt;-&lt;/span&gt; Summit 40L Pack — €89 — lightweight backpack

&lt;span class="gu"&gt;## Policies&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Shipping: EU delivery 2–3 days
&lt;span class="p"&gt;-&lt;/span&gt; Returns: 30 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What surprised me during research
&lt;/h2&gt;

&lt;p&gt;A few observations stood out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most vendor implementations are structurally very similar&lt;/li&gt;
&lt;li&gt;Marketing differences are larger than technical differences&lt;/li&gt;
&lt;li&gt;JSONL-style structured output is rarely implemented, despite being more machine-friendly&lt;/li&gt;
&lt;li&gt;There is still no confirmed adoption standard among major AI platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words: the ecosystem is early and still converging.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key takeaway
&lt;/h2&gt;

&lt;p&gt;For most Magento stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don't need a complex solution to start&lt;/li&gt;
&lt;li&gt;Manual or lightweight generation is often enough&lt;/li&gt;
&lt;li&gt;Automation only matters at scale or high change frequency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real long-term value is not the file itself, but how consistently your product data is structured for machines.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; should not be treated as a magic SEO layer. It is better understood as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a compatibility layer between eCommerce content and AI systems&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whether it becomes important depends less on Magento and more on how AI platforms evolve ingestion of structured web data.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Full comparison with module table, pricing, and FAQ: &lt;a href="https://angeo.dev/llms-txt-magento-2-free-vs-paid-module-comparison/" rel="noopener noreferrer"&gt;angeo.dev/llms-txt-magento-2-free-vs-paid-module-comparison/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>llmstxt</category>
      <category>aeo</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>Shopify vs Magento for AI Commerce in 2026: Platform-Mediated vs Merchant-Controlled AEO</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Thu, 28 May 2026 16:16:18 +0000</pubDate>
      <link>https://dev.to/angeo/shopify-vs-magento-for-ai-commerce-in-2026-platform-mediated-vs-merchant-controlled-aeo-2igm</link>
      <guid>https://dev.to/angeo/shopify-vs-magento-for-ai-commerce-in-2026-platform-mediated-vs-merchant-controlled-aeo-2igm</guid>
      <description>&lt;p&gt;In March 2026, Shopify positioned its eligible merchants for default discovery inside ChatGPT via Agentic Storefronts — no per-merchant setup required. Two months later, the same week Shopify reported its fastest quarterly revenue growth in four years, the stock fell 16%.&lt;/p&gt;

&lt;p&gt;Both facts are true. They describe where AI commerce actually sits in 2026: infrastructure that is genuinely transformative, deployed into a market uncertain whether the near-term economics hold.&lt;/p&gt;

&lt;p&gt;For developers and architects working with Adobe Commerce, Magento 2, or any non-Shopify e-commerce stack, the question is narrower than the stock story: &lt;strong&gt;which architecture gives the merchant the most controllable path to AI commerce visibility — and what does the implementation actually look like in code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article frames the answer through a single distinction: &lt;strong&gt;platform-mediated AI distribution&lt;/strong&gt; (Shopify's bet) versus &lt;strong&gt;Merchant-Controlled AEO&lt;/strong&gt; (the approach Magento merchants build themselves, and increasingly the more defensible long-term position).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read the full version with embedded diagrams on &lt;a href="https://angeo.dev/shopify-vs-magento-ai-commerce-aeo-2026/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Key findings (as of May 2026)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Shopify wins distribution.&lt;/strong&gt; Agentic Storefronts positioned millions of merchants for default ChatGPT visibility in March 2026 — onboarding effort is near-zero for eligible US merchants.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Magento wins control.&lt;/strong&gt; A default Adobe Commerce install scores ~25% on a 9-signal AEO audit. With free open-source modules, 80–90% is achievable in approximately 90 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Both reach the same AI channels.&lt;/strong&gt; ChatGPT, Microsoft Copilot, Google AI Mode, Gemini, and Perplexity are technically accessible from either platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval quality is platform-agnostic.&lt;/strong&gt; JavaScript-rendered content is invisible to AI extraction on both Shopify and Magento by default. The Agentic Commerce Protocol (ACP) feed solves discovery; it does not solve on-page extraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditability differs sharply.&lt;/strong&gt; Magento's AEO signals are inspectable with one CLI command. Shopify's distribution layer is largely opaque to the individual merchant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-store and B2B favor Magento.&lt;/strong&gt; Per-store-view AEO configuration, B2B price books, and ERP integration remain Magento-native territory.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — Shopify wins distribution. Magento wins control. Both reach the same AI channels. The platform choice matters less than the AEO implementation you build on top of it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The two paths to AI commerce visibility
&lt;/h2&gt;

&lt;p&gt;The fundamental difference between the two platforms is architectural, not cosmetic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHOPIFY — Platform-Mediated AI Distribution
Merchant catalog
       ↓
Shopify Catalog (platform-managed)
       ↓
Agentic Commerce Protocol (ACP) syndication
       ↓
OpenAI / Microsoft Copilot / Google AI Mode / Gemini
       ↓
AI recommendation

MAGENTO — Merchant-Controlled AEO
Merchant catalog
       ↓
robots.txt — OAI-SearchBot, PerplexityBot, Google-Extended access
llms.txt — machine-readable catalog map
Product JSON-LD schema (with offers.availability)
ACP product feed (generated locally)
MCP server endpoints (live agent access)
Server-rendered content (extractable by AI crawlers)
       ↓
AI crawler access + retrieval + feed ingestion
       ↓
AI recommendation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shopify handles the distribution layer on the merchant's behalf. Magento exposes the full stack — each signal configured, testable, and auditable by the merchant.&lt;/p&gt;

&lt;p&gt;Neither path is inherently superior. They reflect different philosophies about who controls the infrastructure between a merchant and an AI platform.&lt;/p&gt;




&lt;h2&gt;
  
  
  The state of play: what each platform delivers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Shopify — platform-mediated AI distribution
&lt;/h3&gt;

&lt;p&gt;Shopify's AI commerce strategy is the most significant platform-level AEO development of 2026. Via Agentic Storefronts, &lt;a href="https://www.shopify.com/news/agentic-commerce-momentum" rel="noopener noreferrer"&gt;Shopify positioned its merchant ecosystem for default discovery inside ChatGPT, Microsoft Copilot, Google AI Mode, and the Gemini app&lt;/a&gt; — managed centrally from the Shopify Admin, with no app installation or separate feed submission required from merchants.&lt;/p&gt;

&lt;p&gt;The architecture is technically significant: &lt;a href="https://www.shopify.com/news/shopify-open-ai-commerce" rel="noopener noreferrer"&gt;Shopify describes syndicating real-time pricing, inventory, images, and variants&lt;/a&gt; from the Shopify Catalog to OpenAI's shopping layer via the Agentic Commerce Protocol (ACP). Per Shopify's announcements, merchants who had done nothing specific for AI visibility were positioned for product discoverability inside ChatGPT by default — though actual retrieval consistency and ranking behaviour within ChatGPT's shopping layer are not independently verified.&lt;/p&gt;

&lt;p&gt;Shopify has also announced native Model Context Protocol (MCP) server support via its AI Toolkit — described as enabling AI agents to access live store data including inventory and specifications. Production MCP adoption in commerce is still early-stage, but the infrastructure appears designed for that direction as the ecosystem matures.&lt;/p&gt;

&lt;p&gt;Early reported metrics suggest meaningful traction: &lt;a href="https://finance.yahoo.com/markets/stocks/articles/shopifys-ai-push-sustain-more-161700877.html" rel="noopener noreferrer"&gt;Shopify reported AI-driven traffic surging 8× year-over-year in Q1 2026, with orders from AI-powered searches up nearly 13×&lt;/a&gt; — from a small but growing base.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt; A US-based DTC merchant on Shopify who has done literally nothing for AEO is positioned for ChatGPT visibility by default. That is unprecedented for the SMB segment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Magento — Merchant-Controlled AEO
&lt;/h3&gt;

&lt;p&gt;Adobe Commerce / Magento 2 has no equivalent platform-level arrangement with OpenAI or other AI platforms. Every AEO signal must be configured deliberately. The default Magento 2 installation scores approximately 25% on a 9-signal AEO audit — based on audits across 50+ stores — with three consistent failure points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;robots.txt blocks AI crawlers&lt;/strong&gt; — default wildcard rules prevent OAI-SearchBot, PerplexityBot, and Google-Extended from accessing the store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No llms.txt&lt;/strong&gt; — no machine-readable catalog map is present&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product schema missing &lt;code&gt;offers.availability&lt;/code&gt;&lt;/strong&gt; — required field for ChatGPT Shopping ACP conformance checks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fixing these takes approximately 90 minutes with the right open-source modules. Reaching ChatGPT Shopping eligibility requires a separate application at chatgpt.com/merchants, ACP feed generation, and passing OpenAI's conformance review. There is no automatic path — but the same AI commerce channels are technically reachable through Merchant-Controlled AEO implementation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt; Magento's "disadvantage" is the cost of one afternoon. The "advantage" is that you own and can audit every signal in the stack — which matters more as AI platforms diversify and feed terms evolve.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Real audit output — what Merchant-Controlled AEO looks like
&lt;/h2&gt;

&lt;p&gt;The abstract comparison becomes concrete when you see what the audit actually returns. Here is the output from &lt;code&gt;bin/magento angeo:aeo:audit&lt;/code&gt; on a fully configured Adobe Commerce 2.4.7 store (mid-market apparel, ~14k SKUs, EU multi-store):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bin/magento angeo:aeo:audit &lt;span class="nt"&gt;--store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;default

Running AEO audit &lt;span class="k"&gt;for &lt;/span&gt;store: default
─────────────────────────────────────────────────────────────

✓ PASS  robots.txt              All 10 AI bots permitted
                                  OAI-SearchBot, ChatGPT-User, GPTBot,
                                  PerplexityBot, Google-Extended,
                                  ClaudeBot, Claude-Web, Bingbot,
                                  CCBot, Applebot-Extended

✓ PASS  llms.txt                Generated — 12,400 products mapped
                                Last regenerated: 2026-05-24 03:00 UTC
                                Per-store-view: 4 variants active

✓ PASS  Product JSON-LD         offers.availability present
                                aggregateRating present &lt;span class="o"&gt;(&lt;/span&gt;8,200 / 12,400&lt;span class="o"&gt;)&lt;/span&gt;
                                brand, sku, gtin13 present
                                priceValidUntil present

✓ PASS  ACP product feed        Spec-compliant — 12,400 products
                                Refresh interval: 15 min
                                Last successful &lt;span class="nb"&gt;sync&lt;/span&gt;: 2026-05-25 09:15 UTC
                                OpenAI conformance: PASSED 2026-04-12

✓ PASS  MCP server endpoint     /mcp/v1 active
                                Live inventory + pricing exposed
                                Authentication: bearer token configured

✓ PASS  Server-side rendering   Product description visible &lt;span class="k"&gt;in &lt;/span&gt;HTML
                                No JavaScript-only critical content

✓ PASS  FAQPage schema          On 8 CMS pages
                                Average 6 Q&amp;amp;A pairs per page

✓ PASS  AI order attribution    sales_order.ai_referrer column active
                                Q1 2026: 1,847 orders attributed
                                Top &lt;span class="nb"&gt;source&lt;/span&gt;: ChatGPT &lt;span class="o"&gt;(&lt;/span&gt;62%&lt;span class="o"&gt;)&lt;/span&gt;

⚠ WARN  Canonical consistency   3 product URLs with conflicting hreflang
                                See: var/log/angeo_aeo_warnings.log

─────────────────────────────────────────────────────────────
AEO Score: 91% — Excellent
Time elapsed: 4.2s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Shopify, AI visibility is largely a black box. You can observe whether products appear in ChatGPT responses. You cannot inspect what &lt;code&gt;offers.availability&lt;/code&gt; value Shopify is transmitting for a specific variant via ACP, verify the exact feed format OpenAI is receiving, or audit which products are failing conformance checks and why. If a product is not appearing, the debugging path is indirect.&lt;/p&gt;

&lt;p&gt;That difference — a 4-second CLI output versus an opaque distribution layer — is what "Merchant-Controlled AEO" means in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Retrieval tests — what AI engines actually surface
&lt;/h2&gt;

&lt;p&gt;The capability tables describe theoretical reach. Retrieval tests describe what AI engines actually do with the available signals. These are spot-check results from controlled queries run in May 2026 across three store configurations in the same category (industrial test equipment, identical product catalogs replicated across platforms for benchmarking purposes):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Shopify (Agentic SF)&lt;/th&gt;
&lt;th&gt;Magento (default)&lt;/th&gt;
&lt;th&gt;Magento (Merchant-Controlled AEO)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"best Siemens thermal imaging camera under €2k"&lt;/td&gt;
&lt;td&gt;Surfaced — product card&lt;/td&gt;
&lt;td&gt;Absent&lt;/td&gt;
&lt;td&gt;Surfaced — product card + spec citation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Fluke 87V vs Keysight U1242C"&lt;/td&gt;
&lt;td&gt;Surfaced — comparison&lt;/td&gt;
&lt;td&gt;Absent&lt;/td&gt;
&lt;td&gt;Surfaced — citation in editorial answer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"thermal camera with USB-C and 320×240 sensor"&lt;/td&gt;
&lt;td&gt;Partial — generic recs&lt;/td&gt;
&lt;td&gt;Absent&lt;/td&gt;
&lt;td&gt;Surfaced — exact-spec match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"recommend a megohmmeter for industrial use"&lt;/td&gt;
&lt;td&gt;Surfaced — top 3&lt;/td&gt;
&lt;td&gt;Absent&lt;/td&gt;
&lt;td&gt;Surfaced — top 3 with cited specs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"who sells calibrated multimeters in the EU"&lt;/td&gt;
&lt;td&gt;Partial — US-bias&lt;/td&gt;
&lt;td&gt;Absent&lt;/td&gt;
&lt;td&gt;Surfaced — EU retailer cited&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;ChatGPT retrieval spot-checks, May 2026. Same catalog across configurations. Results are illustrative of architectural difference, not exhaustive ranking benchmarks. AI retrieval is non-deterministic; individual query outcomes vary across sessions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Two observations from the test pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Default Magento is invisible.&lt;/strong&gt; Blocked AI bots, missing llms.txt, incomplete schema, and no ACP feed compound into zero retrieval surface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configured Magento matches Shopify on retrieval — and sometimes exceeds it on EU-specific and spec-driven queries.&lt;/strong&gt; Agentic Storefronts is currently US-weighted. Detailed spec retrieval depends on schema depth, which Magento exposes more granularly than Shopify's standard product templates.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt; The distribution-versus-control framing is not theoretical. Once a Magento store is configured with Merchant-Controlled AEO, retrieval performance is competitive — and the merchant retains diagnostic control Shopify does not provide.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Full capability comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Shopify&lt;/th&gt;
&lt;th&gt;Magento (configured)&lt;/th&gt;
&lt;th&gt;Magento (default)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ChatGPT Shopping (ACP)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Platform-level via Agentic Storefronts&lt;/td&gt;
&lt;td&gt;✅ Manual — ACP feed + application&lt;/td&gt;
&lt;td&gt;✗ Not configured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Perplexity discovery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Via Shopify Catalog integration&lt;/td&gt;
&lt;td&gt;✅ Via llms.txt + PerplexityBot access&lt;/td&gt;
&lt;td&gt;✗ Bot blocked by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Google AI Mode / Gemini&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Via Agentic Storefronts opt-in&lt;/td&gt;
&lt;td&gt;✅ Via Google Merchant Center + Google-Extended access&lt;/td&gt;
&lt;td&gt;⚠ Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Microsoft Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Active integration&lt;/td&gt;
&lt;td&gt;⚠ Requires custom ACP feed configuration&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP (Model Context Protocol) live agent access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Native in Shopify Admin&lt;/td&gt;
&lt;td&gt;✅ Via angeo/module-openai-product-feed-api&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;llms.txt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠ No native generation&lt;/td&gt;
&lt;td&gt;✅ angeo/module-llms-txt — per store view&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Product JSON-LD schema&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Better defaults than Luma — incomplete for full ACP compliance&lt;/td&gt;
&lt;td&gt;✅ angeo/module-rich-data — availability, aggregateRating&lt;/td&gt;
&lt;td&gt;⚠ Missing offers.availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI order attribution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Native in Shopify Analytics&lt;/td&gt;
&lt;td&gt;⚠ Requires custom observer to persist to sales_order&lt;/td&gt;
&lt;td&gt;✗ GA4 dark traffic only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;robots.txt AI bot access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Managed by Shopify&lt;/td&gt;
&lt;td&gt;✅ angeo/module-robots-txt-aeo&lt;/td&gt;
&lt;td&gt;✗ Blocked by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-store / B2B / custom data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠ Limited without Shopify Plus&lt;/td&gt;
&lt;td&gt;✅ Native — multi-store, B2B, ERP integration&lt;/td&gt;
&lt;td&gt;✅ Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AEO audit CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠ No CLI audit — manual checking only&lt;/td&gt;
&lt;td&gt;✅ angeo/module-aeo-audit — 9 signals, one command&lt;/td&gt;
&lt;td&gt;✅ Same&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Where Shopify's advantage is real
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Platform-level distribution via ACP
&lt;/h3&gt;

&lt;p&gt;The Shopify–OpenAI partnership, based on public announcements, is a structural distribution advantage — not a parity feature. Per Shopify's documentation, eligible merchants were positioned for default ChatGPT discoverability through Agentic Storefronts and the Agentic Commerce Protocol without individual action. No equivalent arrangement exists for Adobe Commerce or Magento merchants. Adobe has not announced a comparable platform-level integration with any AI shopping platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Native AI attribution
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.shopify.com/blog/aeo-for-ecommerce" rel="noopener noreferrer"&gt;Shopify Analytics natively filters sessions and orders by AI referrer&lt;/a&gt;. For Magento, even basic AI attribution requires custom observer code to persist referrer data to &lt;code&gt;sales_order&lt;/code&gt;. The measurement infrastructure Shopify includes by default takes several hours of custom development on Magento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed to AI visibility
&lt;/h3&gt;

&lt;p&gt;For a merchant starting from zero, Shopify's path to AI commerce visibility is measured in hours — or zero, given Agentic Storefronts default activation. For Magento, the path requires sequential steps: AEO audit, robots.txt fix, llms.txt generation, schema update, ACP feed generation, merchant application, and OpenAI conformance review. Total elapsed time: days to weeks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Shopify thesis in one sentence:&lt;/strong&gt; If you accept platform-mediated AI distribution, Shopify delivers it faster and more completely than any alternative on the market.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Where Magento's advantage is real
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Control and auditability — the Merchant-Controlled AEO position
&lt;/h3&gt;

&lt;p&gt;Every AI signal in Magento's AEO stack is explicitly configured, testable, and auditable with a single CLI command (see the audit output above). On Shopify, AI visibility is largely a black box. You can observe whether products appear in ChatGPT responses. You cannot inspect what ACP feed payload Shopify is transmitting for a specific variant, verify the exact format OpenAI is receiving, or audit which products are failing conformance checks and why.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-store architecture
&lt;/h3&gt;

&lt;p&gt;Shopify's AI capabilities are primarily designed for single-brand storefronts. For merchants running multiple stores with different catalogs, languages, currencies, or B2B price books — Magento's native multi-store architecture provides per-store control over every AEO signal. Separate &lt;code&gt;llms.txt&lt;/code&gt; per store view, different schema configurations per locale, precise ACP feed control per market.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open standards, no vendor lock-in
&lt;/h3&gt;

&lt;p&gt;The signals Merchant-Controlled AEO is built on are open standards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;robots.txt&lt;/strong&gt; — 30-year-old RFC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON-LD&lt;/strong&gt; — W3C standard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic Commerce Protocol (ACP)&lt;/strong&gt; — OpenAI's open spec, adoptable by any merchant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; — Anthropic's open spec&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;llms.txt&lt;/strong&gt; — emerging community convention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A merchant running Merchant-Controlled AEO reaches any AI engine that speaks these protocols — present and future. A merchant on Shopify reaches the platforms Shopify has agreements with. The first scales with the protocol layer; the second scales with the platform's BD team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data ownership
&lt;/h3&gt;

&lt;p&gt;When a Shopify merchant uses Agentic Storefronts, their product data — pricing, inventory, variant configuration — flows through Shopify's infrastructure to AI platforms via ACP. The merchant does not control the update frequency beyond what Shopify allows, or verify the representation of their products in AI responses. On Magento, the ACP feed is generated locally, validated locally, and transmitted directly. The merchant controls exactly what AI platforms receive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Magento thesis in one sentence:&lt;/strong&gt; If you want to own the infrastructure between your catalog and AI platforms — and audit it — Merchant-Controlled AEO on Adobe Commerce is the only mainstream option that delivers it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The gap neither platform fully solves
&lt;/h2&gt;

&lt;p&gt;Both Shopify and Magento share a structural limitation independent of platform choice: &lt;strong&gt;JavaScript rendering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI extraction systems do not reliably execute client-side rendering. Shopify's standard product themes use JavaScript for variant selection and dynamic content. Magento's Luma theme uses RequireJS tabs that collapse the product description on load.&lt;/p&gt;

&lt;p&gt;In both cases, content hidden behind JavaScript is often invisible to AI extraction pipelines — regardless of how comprehensive the ACP structured data feed is. The feed provides product data for shopping interfaces; crawled page content provides context for retrieval and editorial recommendations. Both matter. Agentic Storefronts solve the feed discovery problem. They do not solve the on-page extraction problem for content-based AI visibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  Which platform for which merchant
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Merchant profile&lt;/th&gt;
&lt;th&gt;Better fit&lt;/th&gt;
&lt;th&gt;Primary reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DTC brand, &amp;lt;10k SKUs, US market, speed priority&lt;/td&gt;
&lt;td&gt;Shopify&lt;/td&gt;
&lt;td&gt;Agentic Storefronts positions catalog for ChatGPT by default via ACP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-store, multi-language, EU / APAC primary&lt;/td&gt;
&lt;td&gt;Magento&lt;/td&gt;
&lt;td&gt;Per-store AEO configuration; Shopify AI features US-first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B2B manufacturer or distributor&lt;/td&gt;
&lt;td&gt;Magento&lt;/td&gt;
&lt;td&gt;Complex catalog depth, B2B pricing, ERP integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mid-market brand, existing Shopify store&lt;/td&gt;
&lt;td&gt;Shopify&lt;/td&gt;
&lt;td&gt;Native AI attribution, ACP feed management, Copilot integration live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise Adobe Commerce, technical team&lt;/td&gt;
&lt;td&gt;Magento (Merchant-Controlled AEO)&lt;/td&gt;
&lt;td&gt;Data ownership, auditability, custom AEO implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The real shift isn't Shopify vs Magento
&lt;/h2&gt;

&lt;p&gt;The platform debate is the surface. The deeper question — the one that will define commerce infrastructure for the next decade — is whether AI commerce becomes &lt;strong&gt;platform-mediated&lt;/strong&gt; or &lt;strong&gt;merchant-controlled&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Shopify is betting on centralized AI distribution. Agentic Storefronts, native ACP syndication, Shopify-managed MCP endpoints, AI attribution baked into Shopify Analytics — every piece reinforces a single architectural premise: the platform sits between the merchant and the AI layer, and that is the value proposition.&lt;/p&gt;

&lt;p&gt;Adobe Commerce / Magento 2 still allows direct infrastructure ownership. The ACP feed is generated locally. The MCP server runs on the merchant's stack. The llms.txt is regenerated by the merchant's cron. The AEO audit is the merchant's CLI command. Every signal in the AI commerce pipeline is the merchant's to inspect, change, version-control, and migrate.&lt;/p&gt;

&lt;p&gt;For SMB DTC, platform-mediated distribution is probably the right trade. The merchant gets ChatGPT visibility without learning ACP. Shopify takes the operational complexity.&lt;/p&gt;

&lt;p&gt;For mid-market and enterprise — especially merchants with multi-store architecture, B2B obligations, regulatory locality requirements, or strategic catalog data that should not transit through a third-party distribution layer — &lt;strong&gt;Merchant-Controlled AEO&lt;/strong&gt; is increasingly the more defensible position. Not because Shopify's offering is weak, but because the value of owning the infrastructure between your catalog and the AI layer grows as that layer becomes more economically significant.&lt;/p&gt;

&lt;p&gt;Shopify won the first round of AI commerce distribution. The second round — retrieval quality, content accuracy, citation authority, attribution measurement, multi-channel feed control — is more level, and increasingly favors merchants who can own and audit their stack.&lt;/p&gt;

&lt;p&gt;In 2026, the choice between platform-mediated AI distribution and Merchant-Controlled AEO is more consequential than the choice between storefront features themselves.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://angeo.dev/shopify-vs-magento-ai-commerce-aeo-2026/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt; with embedded architecture diagrams and AEO score progression charts. The &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;angeo/module-aeo-audit&lt;/a&gt; checks all 9 Merchant-Controlled AEO signals for Adobe Commerce / Magento 2 stores in one CLI command.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>ai</category>
      <category>magento</category>
      <category>shopify</category>
    </item>
    <item>
      <title>Adobe Commerce Cloud now costs $40k/year. We migrated from Adobe Commerce to Magento Open Source — here's the honest breakdown</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Mon, 25 May 2026 19:47:11 +0000</pubDate>
      <link>https://dev.to/angeo/adobe-commerce-cloud-now-costs-40kyear-we-migrated-from-adobe-commerce-to-magento-open-source--2861</link>
      <guid>https://dev.to/angeo/adobe-commerce-cloud-now-costs-40kyear-we-migrated-from-adobe-commerce-to-magento-open-source--2861</guid>
      <description>&lt;p&gt;Adobe Commerce Cloud licence pricing crossed $40k/year in 2026 for many mid-market merchants. Three of our clients hit that wall over the past 14 months and asked the same question: is migrating to Magento Open Source actually worth it?&lt;/p&gt;

&lt;p&gt;We ran all three migrations. Two were worth it. One wasn't.&lt;/p&gt;

&lt;p&gt;This is the honest version of that story — including the database schema gotchas, the B2B Suite trap, and the cost math nobody puts in marketing posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Migration saves $100k-250k over 5 years IF you don't depend on Adobe-only features&lt;/li&gt;
&lt;li&gt;B2B Suite, Adobe Sensei, and staging features are the three biggest dependency traps&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;row_id&lt;/code&gt; vs &lt;code&gt;entity_id&lt;/code&gt; schema difference will break custom modules that bypass Repository pattern&lt;/li&gt;
&lt;li&gt;Two-thirds of mid-market merchants pay for features they don't use — the other third critically depend on them&lt;/li&gt;
&lt;li&gt;Open Source is the same Magento 2 framework. What changes is the licensing, infrastructure, and a handful of proprietary modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this conversation is happening now
&lt;/h2&gt;

&lt;p&gt;For years Adobe Commerce Cloud was the "safe" choice for mid-market merchants doing $1M-$10M GMV. You paid the license, you got hosting + auto-deploys + B2B + AI recommendations + Adobe's support, and you didn't have to think about infrastructure.&lt;/p&gt;

&lt;p&gt;That math is shifting in 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;License pricing has climbed steeply (we've seen $22k → $40k+ jumps on renewal)&lt;/li&gt;
&lt;li&gt;Adobe's roadmap focus has shifted toward Adobe Experience Manager integrations, not core Commerce features&lt;/li&gt;
&lt;li&gt;The Hyvä ecosystem has reached production maturity on Open Source&lt;/li&gt;
&lt;li&gt;Self-managed hosting (Hypernode, MGT, Cloudways) is now operationally as smooth as Adobe Cloud was three years ago&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The merchants asking us about migration aren't doing it to save $10k. They're doing it because Adobe's value proposition no longer matches what they need.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually stays the same
&lt;/h2&gt;

&lt;p&gt;Both platforms share the Magento 2 core. If your team works in Magento daily, this part doesn't change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Module structure and DI XML&lt;/li&gt;
&lt;li&gt;GraphQL schema and REST API&lt;/li&gt;
&lt;li&gt;Composer-based dependency management&lt;/li&gt;
&lt;li&gt;Admin layout and UI components&lt;/li&gt;
&lt;li&gt;Frontend stack (Luma, Hyvä, PWA Studio, custom headless — all work either way)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bin/magento&lt;/code&gt; CLI commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why "migration" is a misleading word. You're not moving to a different platform. You're removing the Adobe layer from the same platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually breaks — the technical reality
&lt;/h2&gt;

&lt;p&gt;This is where I disagree with most write-ups on this topic. The migration is not "smooth" or "straightforward." It has specific failure modes, and pretending otherwise leads to blown timelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The &lt;code&gt;row_id&lt;/code&gt; vs &lt;code&gt;entity_id&lt;/code&gt; schema split
&lt;/h3&gt;

&lt;p&gt;Adobe Commerce uses &lt;code&gt;row_id&lt;/code&gt; in catalog tables (catalog_product_entity, catalog_category_entity) to support staging and preview features. Open Source uses &lt;code&gt;entity_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If your codebase has SQL that queries these tables directly — instead of going through Magento's Repository pattern — those queries silently break:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Will break after migration&lt;/span&gt;
&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SELECT * FROM catalog_product_entity WHERE row_id = &lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Will keep working — uses repository pattern&lt;/span&gt;
&lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Across three projects we found ~40 places where developers had bypassed Repository for "performance reasons." Each one needed identification and rewrite. Plan for a full audit, not a global find-replace.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The B2B Suite trap
&lt;/h3&gt;

&lt;p&gt;Adobe's B2B Suite isn't just a feature — it's an architectural dependency. Company accounts, shared catalogs, quote workflows, requisition lists, and tiered pricing for company structures all live in this module.&lt;/p&gt;

&lt;p&gt;If you use it, your options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rebuild from scratch (8-12 weeks of senior dev time)&lt;/li&gt;
&lt;li&gt;Replace with paid alternatives (Aitoc, Wyomind, Magexperts have partial coverage)&lt;/li&gt;
&lt;li&gt;Drop the functionality (sometimes acceptable, often not)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no migration path. The data export is partial. The schema doesn't map cleanly. We've seen this kill migration projects in week 2.&lt;/p&gt;

&lt;p&gt;If you depend on B2B Suite, get a specific rebuild estimate BEFORE committing to migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Adobe Sensei recommendation widgets
&lt;/h3&gt;

&lt;p&gt;This one's quieter and easier to miss. Sensei (Adobe's AI recommendation engine) leaves orphaned database tables and broken admin pages after migration if you don't clean them up explicitly.&lt;/p&gt;

&lt;p&gt;Replacement options for product recommendations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-hosted ML&lt;/li&gt;
&lt;li&gt;Open source modules (mgt-commerce/related-products, amasty/recommendations)&lt;/li&gt;
&lt;li&gt;Rebuild on top of Magento's native related products engine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None are drop-in. Budget 2-4 weeks for whatever you choose.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Page Builder content drift
&lt;/h3&gt;

&lt;p&gt;Page Builder content stored in CMS pages mostly survives migration — Open Source has Page Builder too. But Commerce-Cloud-only widgets (dynamic blocks tied to customer segments, staged content) render as empty divs.&lt;/p&gt;

&lt;p&gt;Audit every CMS page before go-live. Replace dynamic blocks with static content or third-party segmentation modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Hosting migration is bigger than it sounds
&lt;/h3&gt;

&lt;p&gt;This is the one teams underestimate most.&lt;/p&gt;

&lt;p&gt;Adobe Cloud abstracts away Fastly, Platform.sh, cron jobs, deploy hooks, secrets management — you don't notice them because they "just work." When you move to Hypernode or similar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fastly VCL → rebuild or migrate to Varnish&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.magento.app.yaml&lt;/code&gt; → your CI/CD pipeline&lt;/li&gt;
&lt;li&gt;Adobe Cloud variables → environment management (we use Vault)&lt;/li&gt;
&lt;li&gt;Cron jobs → manual provisioning&lt;/li&gt;
&lt;li&gt;Deploy hooks → custom GitHub Actions / GitLab CI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plan ~2 weeks of DevOps work. Not optional.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost math — honest version
&lt;/h2&gt;

&lt;p&gt;Mid-market store, $2-3M GMV, 5-year comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adobe Commerce Cloud:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Licence ($30k/yr × 5)&lt;/td&gt;
&lt;td&gt;$150,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adobe support&lt;/td&gt;
&lt;td&gt;included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$150,000&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Magento Open Source (post-migration):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Licence&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting ($8k/yr × 5)&lt;/td&gt;
&lt;td&gt;$40,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev partner / in-house ($20k/yr × 5)&lt;/td&gt;
&lt;td&gt;$100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One-time migration&lt;/td&gt;
&lt;td&gt;$40,000-80,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$180,000-220,000&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 5-year savings ARE real — but they're mostly real for merchants who already have an in-house Magento dev OR a long-term dev partner relationship. If you'd need to hire a partner from scratch just to run Open Source, the math gets thinner.&lt;/p&gt;

&lt;p&gt;Where the savings genuinely show up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Year 6 onward (migration is amortised, licence still $0)&lt;/li&gt;
&lt;li&gt;When Adobe raises the licence at renewal (commonly 15-20% increases)&lt;/li&gt;
&lt;li&gt;When you'd otherwise need infrastructure Adobe Cloud doesn't allow (custom Redis, specific regions, headless storefronts with edge compute)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Decision framework
&lt;/h2&gt;

&lt;p&gt;Migrate if you can say yes to most of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Licence cost ≥ $25k/year&lt;/li&gt;
&lt;li&gt;You use ≤30% of Adobe-only features (no B2B Suite, light Sensei usage, no staging dependency)&lt;/li&gt;
&lt;li&gt;Team has senior Magento experience (or trusted partner)&lt;/li&gt;
&lt;li&gt;You want infrastructure flexibility Adobe doesn't allow&lt;/li&gt;
&lt;li&gt;You're already planning major dev work (replatform, redesign, headless)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay on Adobe if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Heavy B2B Suite usage&lt;/li&gt;
&lt;li&gt;Compliance requirements where Adobe SLA matters&lt;/li&gt;
&lt;li&gt;No DevOps capacity for self-managed infrastructure&lt;/li&gt;
&lt;li&gt;Licence is bundled with other Adobe products you actively use&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The one migration we didn't recommend
&lt;/h2&gt;

&lt;p&gt;Of the three I mentioned at the top, the one we didn't migrate was a B2B distributor with deep Sensei + B2B Suite usage. Their license was $35k/yr — meaningful money — but rebuilding their B2B functionality would have cost ~$120k, and Sensei replacement another $40k. Payback was ~7 years before infrastructure savings, and they didn't have the DevOps capacity to manage it.&lt;/p&gt;

&lt;p&gt;Sometimes the answer is "Adobe is expensive AND it's still the right choice." That's worth saying out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd ask before migrating
&lt;/h2&gt;

&lt;p&gt;If you're considering this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List every Adobe-only feature you use. Score each one 1-5 on "how critical"&lt;/li&gt;
&lt;li&gt;Get a specific rebuild cost for everything you score 4-5&lt;/li&gt;
&lt;li&gt;Add to that: migration cost, 2 weeks of DevOps, 6-12 months of dev partner ramp-up&lt;/li&gt;
&lt;li&gt;Compare to 5-year licence cost INCLUDING expected annual increases&lt;/li&gt;
&lt;li&gt;If self-managed math wins by less than 20%, stay. The risk premium isn't worth a marginal saving.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;If you've migrated recently — what was the schema or dependency gotcha you didn't see coming? I'm collecting war stories for a deeper post on the technical pitfalls specifically.&lt;/p&gt;

&lt;p&gt;Full cost breakdown and FAQ on the canonical: &lt;a href="https://angeo.dev/migrating-from-adobe-commerce-cloud-to-magento-open-source-is-it-worth-it/" rel="noopener noreferrer"&gt;https://angeo.dev/migrating-from-adobe-commerce-cloud-to-magento-open-source-is-it-worth-it/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>ecommerce</category>
      <category>php</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Magento multi-store bug every AI description generator has — and how we fixed it</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Fri, 22 May 2026 05:02:09 +0000</pubDate>
      <link>https://dev.to/angeo/the-magento-multi-store-bug-every-ai-description-generator-has-and-how-we-fixed-it-59b1</link>
      <guid>https://dev.to/angeo/the-magento-multi-store-bug-every-ai-description-generator-has-and-how-we-fixed-it-59b1</guid>
      <description>&lt;p&gt;A client came to us with 8,000 SKUs across four store views — English, Dutch, German, French. Descriptions were either copied from supplier PDFs or missing entirely. The fix was obviously AI generation. The less obvious problem was that &lt;strong&gt;every existing module we evaluated had the same architectural bug&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So we built our own, made it MIT-licensed, and put it on Packagist. This post is about the bug, the fix, and the four-provider abstraction (including a free one) we shipped on top.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🔗 Originally published on &lt;a href="https://angeo.dev/magento-2-ai-product-description-generator/" rel="noopener noreferrer"&gt;https://angeo.dev/magento-2-ai-product-description-generator/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The bug nobody talks about
&lt;/h2&gt;

&lt;p&gt;Most Magento 2 AI content modules call this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;editMode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setCustomAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$generated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine. It isn't. Without an explicit &lt;code&gt;$storeId&lt;/code&gt;, this loads and saves in the &lt;strong&gt;default scope&lt;/strong&gt; — Magento's global, store-view-independent fallback. When you save back, you overwrite &lt;strong&gt;every store view at once&lt;/strong&gt;. The Dutch store gets English descriptions. The German store gets English descriptions. The French store gets English descriptions.&lt;/p&gt;

&lt;p&gt;This is not a configuration problem. The multi-store architecture works correctly — the tooling ignores it. Writing to the default scope is simpler to implement than writing per store. Every commercial module we tested took the simpler path.&lt;/p&gt;

&lt;p&gt;The right way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Load the product in the target store scope&lt;/span&gt;
&lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$storeId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setCustomAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$generated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Save with explicit store scope (Magento_Catalog\Model\Product\Action)&lt;/span&gt;
&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;updateAttributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$generated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$storeId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is one parameter. The architectural cost is iterating stores around your generation loop. The data cost of skipping it is silently corrupting your multi-language catalog.&lt;/p&gt;

&lt;h2&gt;
  
  
  The framework around the fix
&lt;/h2&gt;

&lt;p&gt;The store-scope fix is the boring part. The interesting part is everything you need around it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────┐
│       Angeo Multi-Store AI Content Framework        │
├──────────────┬──────────────────┬───────────────────┤
│  SKU Source  │ Store Iteration  │   AI Provider     │
│  ──────────  │  ──────────────  │  ──────────────── │
│  Catalog     │  Store 1 (EN)    │  OpenAI           │
│  G.Sheets    │  Store 2 (NL)    │  Claude           │
│  CLI --sku   │  Store 3 (DE)    │  Gemini           │
│              │  Store 4 (FR)    │  Groq (free)      │
├──────────────┴──────────────────┴───────────────────┤
│               Content Pipeline                      │
│  load(sku, storeId) → prompt → generate → save      │
├─────────────────────────────────────────────────────┤
│                    Output                           │
│  Magento DB · Local CSV · Google Sheets API v4      │
└─────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Provider Layer&lt;/strong&gt; — uniform interface across OpenAI, Claude, Gemini, Groq&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store Iteration Layer&lt;/strong&gt; — resolves all active store views before processing any SKUs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Pipeline&lt;/strong&gt; — for each store × SKU: load in scope → build prompt → generate → save in scope&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I/O Layer&lt;/strong&gt; — reads SKUs from catalog, Google Sheet, or CLI; writes to Magento DB, CSV, and Google Sheets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The provider abstraction is the part most people will copy. One interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;AiProviderInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wired in &lt;code&gt;di.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;type&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Angeo\AiDescriptionUpdater\Service\AiProviderService"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;arguments&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"providers"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"array"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"openai"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"object"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...OpenAiProvider&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"claude"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"object"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...ClaudeProvider&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"gemini"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"object"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...GeminiProvider&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"groq"&lt;/span&gt;   &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"object"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...GroqProvider&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/argument&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/arguments&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding a fifth provider is one class + one line. The pipeline, store iteration, and I/O don't change. This is the pattern, not just the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four-provider benchmark
&lt;/h2&gt;

&lt;p&gt;200 product descriptions from a real Dutch jewellery store, same system prompt, same product names, all four providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed (avg per description)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Avg. time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Groq&lt;/td&gt;
&lt;td&gt;llama-3.3-70b-versatile&lt;/td&gt;
&lt;td&gt;0.8s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Groq&lt;/td&gt;
&lt;td&gt;mixtral-8x7b-32768&lt;/td&gt;
&lt;td&gt;0.6s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;gemini-2.0-flash&lt;/td&gt;
&lt;td&gt;1.2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;claude-haiku-4-5&lt;/td&gt;
&lt;td&gt;1.1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;gpt-4.1-mini&lt;/td&gt;
&lt;td&gt;1.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;gpt-4.1&lt;/td&gt;
&lt;td&gt;2.1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;claude-sonnet-4-6&lt;/td&gt;
&lt;td&gt;2.8s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For 32,000 generations (8,000 SKUs × 4 store views): &lt;strong&gt;Groq ≈ 7 hours, GPT-4.1 ≈ 19 hours&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost (per 1,000 descriptions, ~200 words each)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Cost / 1k&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Groq&lt;/td&gt;
&lt;td&gt;llama-3.3-70b-versatile&lt;/td&gt;
&lt;td&gt;$0.00 (free tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;gemini-2.0-flash&lt;/td&gt;
&lt;td&gt;~$0.08&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;gpt-4.1-mini&lt;/td&gt;
&lt;td&gt;~$0.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;claude-haiku-4-5&lt;/td&gt;
&lt;td&gt;~$0.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;gpt-4.1&lt;/td&gt;
&lt;td&gt;~$1.80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;claude-sonnet-4-6&lt;/td&gt;
&lt;td&gt;~$2.40&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quality (manual review of 200 samples)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Groq Llama 3.3&lt;/th&gt;
&lt;th&gt;GPT-4.1-mini&lt;/th&gt;
&lt;th&gt;GPT-4.1&lt;/th&gt;
&lt;th&gt;Claude Sonnet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Factual accuracy&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language fluency&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO keyword use&lt;/td&gt;
&lt;td&gt;★★★☆☆&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML formatting&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Practical recommendation:&lt;/strong&gt; Validate prompts with Groq first — it's free, fast, and good enough to test workflow. Production on GPT-4.1-mini if SEO keyword density matters. Flagship products on GPT-4.1 or Claude Sonnet if copy quality directly affects conversion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Groq matters
&lt;/h2&gt;

&lt;p&gt;Groq's free tier is 14,400 requests/day. No credit card. Llama 3.3 70B output quality is genuinely good — ~1 star behind GPT-4.1 in our review, mostly on SEO keyword density.&lt;/p&gt;

&lt;p&gt;For 8,000 SKUs × 4 stores = 32,000 calls, you're at ~1.85 days on the free tier. For most stores under 5,000 SKUs, this is &lt;strong&gt;free production-grade AI content generation&lt;/strong&gt; if you're patient.&lt;/p&gt;

&lt;p&gt;No other Magento module supports Groq at time of writing. This was the killer feature for our client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-ai-description-updater
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First run (Groq, ~5 minutes from zero):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Get a free API key at console.groq.com&lt;/span&gt;
&lt;span class="c"&gt;# 2. In admin: Stores → Configuration → Angeo → AI Description Updater&lt;/span&gt;
&lt;span class="c"&gt;#    AI Provider = Groq (Free), paste key, Dry Run = Yes&lt;/span&gt;
&lt;span class="c"&gt;# 3. Test on one SKU&lt;/span&gt;
bin/magento angeo:ai-description:run &lt;span class="nt"&gt;--sku&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MY-SKU-001 &lt;span class="nt"&gt;--dry-run&lt;/span&gt;

&lt;span class="c"&gt;# 4. If output looks good, disable dry-run and run the batch&lt;/span&gt;
bin/magento angeo:ai-description:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other useful flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:ai-description:run &lt;span class="nt"&gt;--sku&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ABC-123     &lt;span class="c"&gt;# single SKU, all stores&lt;/span&gt;
bin/magento angeo:ai-description:run &lt;span class="nt"&gt;--store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2         &lt;span class="c"&gt;# single store view&lt;/span&gt;
bin/magento angeo:ai-description:run &lt;span class="nt"&gt;--dry-run&lt;/span&gt;         &lt;span class="c"&gt;# generate, don't save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CLI-first by design. The 8,000-SKU client doesn't want a UI; they want cron.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's open source
&lt;/h2&gt;

&lt;p&gt;The honest answer: distribution. We sell AEO audits and full-stack Magento services. The modules are how stores find us. The code is free; the expertise applied to a specific store is not.&lt;/p&gt;

&lt;p&gt;It's a familiar model — Vercel does it with Next.js, Sentry does it with sentry-php. The artefact is open; the operator is the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways for Magento devs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Default-scope writes are silent multi-store corruption.&lt;/strong&gt; Audit any AI/content module before installing on a multi-store catalog. Look for &lt;code&gt;$storeId&lt;/code&gt; parameters in &lt;code&gt;productRepository-&amp;gt;get()&lt;/code&gt; and save calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider abstraction is one interface plus a &lt;code&gt;di.xml&lt;/code&gt; array.&lt;/strong&gt; Don't hardcode OpenAI. Future you (or future LLM pricing) will thank you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groq is the current sweet spot for free Magento AI generation.&lt;/strong&gt; Llama 3.3 70B output is production-acceptable for most stores; the 14,400/day cap is workable for catalogs under ~5,000 SKUs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPT-4.1-mini is the best paid-tier value.&lt;/strong&gt; Comparable to GPT-4.1 at ~17% of the cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI + cron beats admin UI for catalogs above ~500 SKUs.&lt;/strong&gt; Click-by-click generation isn't a workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Module on Packagist:&lt;/strong&gt; &lt;a href="https://packagist.org/packages/angeo/module-ai-description-updater" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-ai-description-updater&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full benchmark + FAQ:&lt;/strong&gt; &lt;a href="https://angeo.dev/magento-2-ai-product-description-generator/" rel="noopener noreferrer"&gt;angeo.dev/magento-2-ai-product-description-generator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why AI search changes Magento descriptions:&lt;/strong&gt; &lt;a href="https://angeo.dev/magento-product-descriptions-in-the-age-of-ai-search/" rel="noopener noreferrer"&gt;angeo.dev/magento-product-descriptions-in-the-age-of-ai-search&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The technical why:&lt;/strong&gt; &lt;a href="https://angeo.dev/magento-product-description-invisible-ai-chatgpt/" rel="noopener noreferrer"&gt;angeo.dev/magento-product-description-invisible-ai-chatgpt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://angeo.dev/magento-2-ai-product-description-generator/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;. Questions or feedback — drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>ai</category>
      <category>opensource</category>
      <category>php</category>
    </item>
    <item>
      <title>The Magento product description that AI can't read</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Fri, 15 May 2026 07:03:48 +0000</pubDate>
      <link>https://dev.to/angeo/the-magento-product-description-that-ai-cant-read-bm2</link>
      <guid>https://dev.to/angeo/the-magento-product-description-that-ai-cant-read-bm2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://angeo.dev/magento-product-description-invisible-ai-chatgpt/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You installed robots.txt rules for GPTBot and OAI-SearchBot. You generated &lt;code&gt;llms.txt&lt;/code&gt;. You added Product schema. The AEO audit is mostly green.&lt;/p&gt;

&lt;p&gt;And ChatGPT still recommends your competitor.&lt;/p&gt;

&lt;p&gt;There is a good chance the problem is not in any of those signals. It is in your product page itself — specifically in how Magento renders product content relative to what AI extraction systems actually process.&lt;/p&gt;




&lt;h2&gt;
  
  
  How your product page travels through an AI recommendation system
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Magento HTML response
         ↓
AI crawler fetches raw HTML
(limited or no JavaScript rendering)
         ↓
Extraction layer parses text, headings, structured data
         ↓
Content chunking — splits page into retrievable units
         ↓
Relevance scoring — ranks chunks against query intent
         ↓
LLM answer synthesis — selects candidates for the response
         ↓
Citation / recommendation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extraction layer is where most Magento stores lose. If your product description is collapsed behind a tab, or rendered only after JS executes — your product may never become a strong candidate for prompts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"best trail running shoes under €150"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"comfortable sneakers for all-day walking"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"running shoes with visible air cushioning"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not an &lt;strong&gt;indexing&lt;/strong&gt; problem. It is a &lt;strong&gt;retrieval&lt;/strong&gt; problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Content visibility is not binary
&lt;/h2&gt;

&lt;p&gt;For AI extraction systems, content falls into at least four levels:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;How the content exists&lt;/th&gt;
&lt;th&gt;Extraction reliability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Server-rendered, early in HTML&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Server-rendered but hidden or collapsed&lt;/td&gt;
&lt;td&gt;Reduced — parser-dependent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Present in DOM only after JS execution&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Loaded async after user interaction&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Googlebot runs a full headless Chrome pipeline — levels 2–4 are "indexable enough" for SEO. Most AI crawlers do not. Even where partial rendering exists, JS-dependent content is significantly less reliable for AI extraction than server-rendered HTML.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually happens on a default Magento product page
&lt;/h2&gt;

&lt;p&gt;Magento 2's standard layout wraps descriptions inside a tabs widget (&lt;code&gt;data-mage-init='{"tabs": {...}}'&lt;/code&gt;). In most Luma configs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The description &lt;strong&gt;is&lt;/strong&gt; in the server-rendered HTML — but marked &lt;strong&gt;inactive, collapsed&lt;/strong&gt;, and positioned deep in the document&lt;/li&gt;
&lt;li&gt;It appears after hundreds of characters of navigation markup, widget JSON, form keys, and boilerplate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run this to see what AI actually sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://yourstore.com/your-product-url.html"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import sys, re
html = sys.stdin.read()
text = re.sub(r'&amp;lt;[^&amp;gt;]+&amp;gt;', ' ', html)
text = re.sub(r'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s2"&gt;+', ' ', text).strip()
print(text[:3000])
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you want: product description text appearing clearly in the first 3000 characters.&lt;/p&gt;

&lt;p&gt;What commonly appears: product name, price, SKU, breadcrumb, button text, widget boilerplate — and very little substantive content.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three approaches to fix it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Approach 1 — Make the description tab active by default
&lt;/h3&gt;

&lt;p&gt;Lowest effort. Sets the description tab as active on load so the content is not hidden at the CSS level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- app/design/frontend/YourVendor/YourTheme/Magento_Catalog/layout/catalog_product_view.xml --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;referenceBlock&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product.info.details"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;arguments&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"config"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"array"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"settings"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"array"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"active"&lt;/span&gt; &lt;span class="na"&gt;xsi:type=&lt;/span&gt;&lt;span class="s"&gt;"boolean"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/argument&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/arguments&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/referenceBlock&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeps tab UI intact for visitors. Moves content from Level 2 collapsed → Level 2 visible.&lt;/p&gt;




&lt;h3&gt;
  
  
  Approach 2 — Render description directly above tabs
&lt;/h3&gt;

&lt;p&gt;Moves description to Level 1 — early in the HTML, clearly associated with the product, before any tabs infrastructure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- catalog_product_view.xml override in your theme --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;referenceContainer&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product.info.main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;block&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"Magento\Catalog\Block\Product\View\Description"&lt;/span&gt;
           &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product.description.above.tabs"&lt;/span&gt;
           &lt;span class="na"&gt;template=&lt;/span&gt;&lt;span class="s"&gt;"YourVendor_Theme::product/description-visible.phtml"&lt;/span&gt;
           &lt;span class="na"&gt;after=&lt;/span&gt;&lt;span class="s"&gt;"product.info.price"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/referenceContainer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// view/frontend/templates/product/description-visible.phtml&lt;/span&gt;
&lt;span class="nv"&gt;$description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getProduct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-description-aeo"&lt;/span&gt; &lt;span class="na"&gt;itemprop=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?=&lt;/span&gt; &lt;span class="cm"&gt;/* @noEscape */&lt;/span&gt; &lt;span class="nv"&gt;$description&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the tabs further down for human navigation — description appears in both places, but the extraction-friendly version is unconditional.&lt;/p&gt;




&lt;h3&gt;
  
  
  Approach 3 — Render all tab content into the initial HTML
&lt;/h3&gt;

&lt;p&gt;The most comprehensive fix. All tab content is in the initial HTML response; tabs widget hides non-active tabs via CSS only.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Override of Magento_Catalog::product/view/details.phtml --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-tabs"&lt;/span&gt; &lt;span class="na"&gt;data-mage-init=&lt;/span&gt;&lt;span class="s"&gt;'{"tabs":{"active":0}}'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getGroupChildNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'detailed_info'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$alias&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="nv"&gt;$childBlock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getLayout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$alias&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$childBlock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"data item title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;data-toggle=&lt;/span&gt;&lt;span class="s"&gt;"trigger"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#tab-&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?=&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;escapeHtmlAttr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$alias&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="cp"&gt;&amp;lt;?=&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;escapeHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$childBlock&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"data item content"&lt;/span&gt;
         &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tab-&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?=&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;escapeHtmlAttr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$alias&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
         &lt;span class="na"&gt;data-role=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="cp"&gt;&amp;lt;?=&lt;/span&gt; &lt;span class="nv"&gt;$childBlock&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toHtml&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;endforeach&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI parsers reading raw HTML see everything. Visitors see only the active tab.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hyva Theme
&lt;/h2&gt;

&lt;p&gt;Hyva uses Alpine.js &lt;code&gt;x-show&lt;/code&gt; directives. Description is typically in the HTML — but structural noise around it reduces extraction clarity.&lt;/p&gt;

&lt;p&gt;Most reliable fix: render the description once &lt;strong&gt;outside&lt;/strong&gt; the Alpine component, as clean server-side HTML, early in the product layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- In your Hyva theme's catalog_product_view.xml --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;referenceContainer&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product.info.main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;block&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"Magento\Catalog\Block\Product\View\Description"&lt;/span&gt;
           &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product.description.retrieval"&lt;/span&gt;
           &lt;span class="na"&gt;template=&lt;/span&gt;&lt;span class="s"&gt;"YourVendor_Theme::product/description-server.phtml"&lt;/span&gt;
           &lt;span class="na"&gt;after=&lt;/span&gt;&lt;span class="s"&gt;"product.info.price"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/referenceContainer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Server-side JSON-LD — same rule applies
&lt;/h2&gt;

&lt;p&gt;If your JSON-LD is injected via GTM or hydrated client-side, AI extraction systems often don't see it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Schema delivery&lt;/th&gt;
&lt;th&gt;Availability to AI parsers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server-rendered in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Reliable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inline in &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; before tabs&lt;/td&gt;
&lt;td&gt;Reliable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Injected by GTM after page load&lt;/td&gt;
&lt;td&gt;Often unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hydrated by JS framework on mount&lt;/td&gt;
&lt;td&gt;Often unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deferred script with &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;defer&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Inconsistent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://yourstore.com/your-product.html"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'"@type": "Product"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No output = schema is client-side rendered.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the difference looks like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; — default Magento, description at Level 2, deep in document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;chars:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;breadcrumbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;price&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;markup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;data-mage-init&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;widget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;UI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;boilerplate&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The Nike Air Max 90 features visible Air cushioning..."&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;buried&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;collapsed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;structurally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ambiguous&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; — description at Level 1, early in document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;[~120 chars: minimal structural markup]

The Nike Air Max 90 is built for all-day comfort with visible Air
cushioning in the heel. Upper: leather and synthetic mesh. Weight: 310g.
Outsole: rubber, minimum 20% recycled content. Sizes: EU 38–47.

Key features:
&lt;span class="p"&gt;-&lt;/span&gt; Visible Air unit in heel
&lt;span class="p"&gt;-&lt;/span&gt; Foam midsole
&lt;span class="p"&gt;-&lt;/span&gt; Waffle-pattern rubber outsole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second version is what an extraction system reads when deciding if your product is a strong candidate for &lt;em&gt;"best running shoes with visible air cushioning."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Most AEO guides focus on &lt;strong&gt;what to add&lt;/strong&gt; — llms.txt, schema, AI bot permissions. This problem is about &lt;strong&gt;how content is exposed&lt;/strong&gt;: its position in the document, whether it is server-rendered, and whether AI extraction can reach it without JavaScript.&lt;/p&gt;

&lt;p&gt;The fix in most cases takes under an hour. Layout XML overrides, no new modules, no API keys.&lt;/p&gt;

&lt;p&gt;Run the &lt;code&gt;curl&lt;/code&gt; test on your top-selling product now. If the description text is not readable in the first few thousand characters of the source — you know where the gap is.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;angeo/module-aeo-audit&lt;/a&gt; checks rendering visibility alongside robots.txt, llms.txt, schema, and six other AEO signals in one CLI command.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Full article with schema delivery comparison table and Hyva deep-dive: &lt;a href="https://angeo.dev/magento-product-description-invisible-ai-chatgpt/" rel="noopener noreferrer"&gt;angeo.dev →&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>aeo</category>
      <category>chatgpt</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>Magento 2 Product JSON-LD Schema for AI Search — Complete Guide (2026)</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Tue, 05 May 2026 12:11:41 +0000</pubDate>
      <link>https://dev.to/angeo/magento-2-product-json-ld-schema-for-ai-search-complete-guide-2026-2b41</link>
      <guid>https://dev.to/angeo/magento-2-product-json-ld-schema-for-ai-search-complete-guide-2026-2b41</guid>
      <description>&lt;p&gt;Even if your Magento store ranks well in Google, it may still not appear in AI-generated product results (ChatGPT, Gemini, Perplexity).&lt;/p&gt;

&lt;p&gt;A common reason is missing or incomplete Product schema.&lt;/p&gt;

&lt;p&gt;AI systems rely on structured data to extract pricing and availability. When that data is missing or inconsistent, products may not be eligible for inclusion. This guide covers what is typically missing, why, and how to fix it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Magento 2 outputs microdata by default; JSON-LD is generally more reliable and easier for parsers to consume&lt;/li&gt;
&lt;li&gt;Missing &lt;code&gt;offers.availability&lt;/code&gt; is a common issue that breaks product eligibility for AI-powered shopping results&lt;/li&gt;
&lt;li&gt;Schema injected via GTM is often not visible to non-JavaScript crawlers&lt;/li&gt;
&lt;li&gt;Hyvä Theme does not include product schema out of the box&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What is AI Search?
&lt;/h2&gt;

&lt;p&gt;By "AI search" we refer to systems like ChatGPT browsing (via OAI-SearchBot), Google AI Overviews, Gemini, and Perplexity that extract structured data from pages to generate answers and product listings.&lt;/p&gt;

&lt;p&gt;Unlike traditional search engines that primarily rank links, these systems rely more heavily on structured data like JSON-LD to understand product details — price, availability, ratings — rather than inferring them from HTML layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fangeo.dev%2Fwp-content%2Fuploads%2F2026%2F05%2FMagento-2-Product-JSON-LD-Schema-for-AI-Search-%25E2%2580%2594-2026-Guide.png" alt="Magento 2 Product JSON-LD Schema for AI Search — Complete Guide" width="800" height="533"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Before vs After: Schema and AI Eligibility
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;th&gt;ChatGPT Shopping&lt;/th&gt;
&lt;th&gt;Gemini&lt;/th&gt;
&lt;th&gt;Perplexity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No schema&lt;/td&gt;
&lt;td&gt;❌ Not eligible / rarely shown&lt;/td&gt;
&lt;td&gt;❌ Not eligible&lt;/td&gt;
&lt;td&gt;❌ Rarely cited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microdata only (Luma default)&lt;/td&gt;
&lt;td&gt;⚠️ Partially parsed&lt;/td&gt;
&lt;td&gt;⚠️ Inconsistent&lt;/td&gt;
&lt;td&gt;⚠️ Inconsistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON-LD, missing &lt;code&gt;offers.availability&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;⚠️ Often fails eligibility check&lt;/td&gt;
&lt;td&gt;⚠️ May appear&lt;/td&gt;
&lt;td&gt;⚠️ May appear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full JSON-LD + availability + rating&lt;/td&gt;
&lt;td&gt;✅ Eligible for Shopping results&lt;/td&gt;
&lt;td&gt;✅ Product results&lt;/td&gt;
&lt;td&gt;✅ Cited with price&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why Magento 2 Falls Short for AI Schema
&lt;/h2&gt;

&lt;p&gt;Default Luma theme outputs microdata — the older &lt;code&gt;itemscope&lt;/code&gt;/&lt;code&gt;itemprop&lt;/code&gt; HTML format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Default Magento Luma — often insufficient for AI search --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;itemscope&lt;/span&gt; &lt;span class="na"&gt;itemtype=&lt;/span&gt;&lt;span class="s"&gt;"http://schema.org/Product"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;itemprop=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Product Name&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;itemprop=&lt;/span&gt;&lt;span class="s"&gt;"offers"&lt;/span&gt; &lt;span class="na"&gt;itemscope&lt;/span&gt; &lt;span class="na"&gt;itemtype=&lt;/span&gt;&lt;span class="s"&gt;"http://schema.org/Offer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;itemprop=&lt;/span&gt;&lt;span class="s"&gt;"price"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;49.99&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- offers.availability not present --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three issues worth addressing for AI search:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Microdata vs JSON-LD.&lt;/strong&gt; JSON-LD is generally more reliable because it is self-contained and easier to parse compared to microdata embedded in HTML. Microdata is also more fragile when themes or extensions modify markup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. &lt;code&gt;offers.availability&lt;/code&gt; is missing.&lt;/strong&gt; This field tells AI systems whether a product can actually be purchased. Without a valid value, products may not pass eligibility checks for AI-powered shopping results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. JavaScript-rendered schema may not be indexed.&lt;/strong&gt; While Google Search processes JS-rendered content reasonably well, many AI crawlers rely on the initial HTML response. Schema injected after page load (e.g. via GTM) is often not visible to these crawlers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;On GTM specifically:&lt;/strong&gt; While Google Search may process JavaScript-rendered schema, many AI crawlers rely on the initial HTML response. If all your structured data comes from GTM, there's a good chance AI systems aren't seeing it — even if Google Rich Results Test passes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Real Example
&lt;/h2&gt;

&lt;p&gt;A Magento store with correct pricing but missing &lt;code&gt;offers.availability&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passed Google Rich Results Test ✅&lt;/li&gt;
&lt;li&gt;Had valid microdata with price and name ✅&lt;/li&gt;
&lt;li&gt;Did &lt;strong&gt;not&lt;/strong&gt; appear consistently in AI-generated product listings ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After adding JSON-LD with &lt;code&gt;"availability": "https://schema.org/InStock"&lt;/code&gt; and validating via &lt;code&gt;curl&lt;/code&gt; (server-side output), the product became eligible for AI Shopping results.&lt;/p&gt;

&lt;p&gt;This is the most common schema issue across Magento stores — and it takes about five minutes to fix.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Copy-Paste Product JSON-LD
&lt;/h2&gt;

&lt;p&gt;A spec-compliant block that covers all the fields AI systems look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alpine Hiking Jacket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Waterproof 3-layer shell for alpine conditions."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WB-004"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://yourstore.com/media/catalog/product/jacket.jpg"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TrailMaster"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"offers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Offer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"priceCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"189.99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"priceValidUntil"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-12-31"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/InStock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"itemCondition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/NewCondition"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://yourstore.com/alpine-hiking-jacket.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"seller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your Store Name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aggregateRating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AggregateRating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ratingValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reviewCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"38"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bestRating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"worstRating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Required and Recommended Fields
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Common mistake&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@type: Product&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;td&gt;HTML tags in name string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;offers.availability&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;td&gt;Text string instead of URI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;offers.price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;"€189"&lt;/code&gt; instead of &lt;code&gt;"189.99"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;offers.priceCurrency&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;td&gt;Symbol &lt;code&gt;€&lt;/code&gt; instead of code &lt;code&gt;EUR&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Recommended&lt;/td&gt;
&lt;td&gt;Relative URL instead of absolute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sku&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Recommended&lt;/td&gt;
&lt;td&gt;Often missing entirely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;aggregateRating&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Recommended&lt;/td&gt;
&lt;td&gt;Including when &lt;code&gt;reviewCount&lt;/code&gt; is 0 — causes validation error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;brand&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Recommended&lt;/td&gt;
&lt;td&gt;Plain string instead of &lt;code&gt;{"@type":"Brand","name":"..."}&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  offers.availability — full URI required
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;✅ Correct&lt;/th&gt;
&lt;th&gt;❌ Often rejected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;In stock&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://schema.org/InStock&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;"In Stock"&lt;/code&gt; / &lt;code&gt;"instock"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Out of stock&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://schema.org/OutOfStock&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"Out of Stock"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-order&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://schema.org/PreOrder&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"preorder"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Back order&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://schema.org/BackOrder&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"backorder"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The full schema.org URI is what the spec requires. Short strings are technically invalid — parsers may accept them or silently ignore them depending on the implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Configurable Products — Use AggregateOffer
&lt;/h2&gt;

&lt;p&gt;When individual variants have different availability states, it's cleaner to use &lt;code&gt;AggregateOffer&lt;/code&gt; so AI systems can understand the full option matrix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Running Shoe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"offers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AggregateOffer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"offerCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lowPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89.99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"priceCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/InStock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"offers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Offer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS-42-BLK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Size 42 / Black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/InStock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89.99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"priceCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Offer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS-43-BLK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Size 43 / Black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/OutOfStock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89.99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"priceCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Hyvä Theme — No Schema Out of the Box
&lt;/h2&gt;

&lt;p&gt;Hyvä Theme is built on Alpine.js and does not include Luma's product templates. This means Hyvä Theme does not include product schema out of the box in its default templates — neither microdata nor JSON-LD.&lt;/p&gt;

&lt;p&gt;Verify quickly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/sample-product.html | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'application/ld+json'&lt;/span&gt;
&lt;span class="c"&gt;# Returns 0 → no JSON-LD&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/sample-product.html | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'itemscope'&lt;/span&gt;
&lt;span class="c"&gt;# Returns 0 → no microdata either&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix is to inject JSON-LD via layout XML so it's server-side rendered. Create &lt;code&gt;Vendor_Theme/layout/catalog_product_view.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;page&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
      &lt;span class="na"&gt;xsi:noNamespaceSchemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"urn:magento:framework:View/Layout/etc/page_configuration.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;block&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"Magento\Framework\View\Element\Template"&lt;/span&gt;
               &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product.json.ld"&lt;/span&gt;
               &lt;span class="na"&gt;template=&lt;/span&gt;&lt;span class="s"&gt;"Vendor_Module::product/json-ld.phtml"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/page&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Schema in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; via layout XML is part of the initial HTML response — visible to crawlers that don't execute JavaScript.&lt;/p&gt;

&lt;p&gt;Alternatively, you can use an open-source module like &lt;a href="https://packagist.org/packages/angeo/module-rich-data" rel="noopener noreferrer"&gt;angeo/module-rich-data&lt;/a&gt; (MIT) to generate schema automatically for both Luma and Hyvä.&lt;/p&gt;




&lt;h2&gt;
  
  
  Diagnosing Your Current Schema
&lt;/h2&gt;

&lt;p&gt;This one-liner checks what schema your product pages actually output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/sample-product.html | &lt;span class="se"&gt;\&lt;/span&gt;
  python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import sys, json, re
body = sys.stdin.read()
blocks = re.findall(r'&amp;lt;script[^&amp;gt;]+type=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;application/ld&lt;/span&gt;&lt;span class="se"&gt;\+&lt;/span&gt;&lt;span class="s2"&gt;json&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;[^&amp;gt;]*&amp;gt;(.*?)&amp;lt;/script&amp;gt;', body, re.DOTALL)
for b in blocks:
    try:
        d = json.loads(b)
        items = d if isinstance(d, list) else [d]
        for item in items:
            nodes = item.get('@graph', [item])
            for n in nodes:
                if n.get('@type') in ('Product', 'IndividualProduct'):
                    print('FOUND Product schema')
                    offers = n.get('offers', {})
                    if isinstance(offers, list): offers = offers[0] if offers else {}
                    print('availability:', offers.get('availability', 'MISSING'))
                    print('price:', offers.get('price', 'MISSING'))
                    print('aggregateRating:', 'present' if n.get('aggregateRating') else 'MISSING')
    except: pass
  "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No output&lt;/td&gt;
&lt;td&gt;No JSON-LD schema&lt;/td&gt;
&lt;td&gt;Add it or install a module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;availability: MISSING&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Offers block incomplete&lt;/td&gt;
&lt;td&gt;Fix the offers object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;availability: InStock&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Text string (non-spec)&lt;/td&gt;
&lt;td&gt;Change to full URI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;availability: https://schema.org/InStock&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Correct&lt;/td&gt;
&lt;td&gt;Validate at schema.org&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Implementation Options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1 — Module (5 min)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-rich-data
bin/magento setup:upgrade &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bin/magento cache:flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MIT licensed, works on Luma and Hyvä. Adds Product, Organization, BreadcrumbList, WebSite, FAQPage schema — all server-side rendered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2 — Manual phtml
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;Magento_Catalog/templates/product/json-ld.phtml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getProduct&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'@context'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'https://schema.org/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'@type'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Product'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;'sku'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getSku&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;'offers'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'@type'&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Offer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'price'&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getFinalPrice&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'priceCurrency'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCurrencyCode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'availability'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isAvailable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'https://schema.org/InStock'&lt;/span&gt;
            &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'https://schema.org/OutOfStock'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'itemCondition'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'https://schema.org/NewCondition'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;?=&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;JSON_PRETTY_PRINT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;JSON_UNESCAPED_SLASHES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 3 — GTM
&lt;/h3&gt;

&lt;p&gt;Worth mentioning because it comes up a lot: &lt;strong&gt;GTM-injected schema works for Google Search&lt;/strong&gt;, which processes JavaScript. For AI crawlers that rely on the initial HTML response, GTM schema may not be seen. If you're specifically targeting AI search visibility, server-side rendering is safer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Validation Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] JSON-LD format (not microdata)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;offers.availability&lt;/code&gt; — full schema.org URI&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;offers.price&lt;/code&gt; — number string, no currency symbol&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;offers.priceCurrency&lt;/code&gt; — ISO 4217 code (EUR, USD, GBP)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;image&lt;/code&gt; — at least one absolute URL&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;aggregateRating&lt;/code&gt; omitted if &lt;code&gt;reviewCount&lt;/code&gt; is 0&lt;/li&gt;
&lt;li&gt;[ ] Schema present in raw &lt;code&gt;curl&lt;/code&gt; output (server-side rendered)&lt;/li&gt;
&lt;li&gt;[ ] Hyvä: schema injected via layout XML &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Configurable products use &lt;code&gt;AggregateOffer&lt;/code&gt; with per-variant &lt;code&gt;Offer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Zero errors at &lt;a href="https://validator.schema.org" rel="noopener noreferrer"&gt;validator.schema.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Errors
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;"The value of offers.availability is not valid"&lt;/strong&gt;&lt;br&gt;
Using a text string. Change to &lt;code&gt;"https://schema.org/InStock"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Missing field: offers.priceCurrency"&lt;/strong&gt;&lt;br&gt;
Add &lt;code&gt;"priceCurrency": "EUR"&lt;/code&gt; to the offers object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"ratingValue out of range"&lt;/strong&gt;&lt;br&gt;
Value must be between 1 and &lt;code&gt;bestRating&lt;/code&gt;. A value of 0 is invalid — omit &lt;code&gt;aggregateRating&lt;/code&gt; entirely if no reviews yet.&lt;/p&gt;


&lt;h2&gt;
  
  
  Full AEO Check
&lt;/h2&gt;

&lt;p&gt;Product schema is one of 13 signals that affect AI search visibility in Magento. To check all of them at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-aeo-audit
bin/magento setup:upgrade &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bin/magento cache:flush
bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Free CLI tool — weighted score across 13 signals, exact fix command for each failure.&lt;/p&gt;




&lt;p&gt;If you're debugging Magento schema issues, the CLI audit tool above can save a lot of manual checking.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://angeo.dev/magento-2-product-schema-json-ld-ai-search/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>seo</category>
      <category>ecommerce</category>
      <category>ai</category>
    </item>
    <item>
      <title>Magento 2 AEO Guide: Make Your Store Visible in ChatGPT, Gemini and Perplexity (2026)</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Wed, 29 Apr 2026 20:51:10 +0000</pubDate>
      <link>https://dev.to/angeo/magento-2-aeo-guide-make-your-store-visible-in-chatgpt-gemini-and-perplexity-2026-3mmo</link>
      <guid>https://dev.to/angeo/magento-2-aeo-guide-make-your-store-visible-in-chatgpt-gemini-and-perplexity-2026-3mmo</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR — 2-minute version
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Default Magento 2 stores are largely invisible to AI assistants (~25% AEO score)&lt;/li&gt;
&lt;li&gt;The biggest blockers: &lt;code&gt;robots.txt&lt;/code&gt; blocks AI bots, no &lt;code&gt;llms.txt&lt;/code&gt;, Product schema missing &lt;code&gt;offers.availability&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can audit your store in seconds: &lt;code&gt;bin/magento angeo:aeo:audit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Most stores reach 80%+ AEO in ~90 minutes with basic fixes&lt;/li&gt;
&lt;li&gt;ChatGPT Shopping requires a separate merchant registration at &lt;code&gt;chatgpt.com/merchants&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1digmqoprtksl5k3w0v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1digmqoprtksl5k3w0v.png" alt="Magento 2 AEO Guide 2026 – optimize your store for ChatGPT, Gemini and Perplexity" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've optimized your Magento store for Google. But when a shopper asks ChatGPT &lt;em&gt;"what's a good cast iron pan under $80?"&lt;/em&gt; — your store isn't in the answer.&lt;/p&gt;

&lt;p&gt;That's not an SEO problem. It's an AEO problem. And the fixes are completely different.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI assistants are becoming a product discovery layer — not just a search tool. When a user asks for a recommendation, they've already formed intent. If your store isn't accessible to these systems, you're invisible at exactly that moment. That's a different problem from ranking fifth in Google — it's not being in the conversation at all.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This guide covers all 9 AEO signals for Magento 2, what each one means, and how to fix every gap — with exact CLI commands. The tooling referenced is open-source and on &lt;a href="https://packagist.org/packages/angeo/" rel="noopener noreferrer"&gt;Packagist&lt;/a&gt;, but the signal framework applies to any Magento implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key terms
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AEO — AI Engine Optimization&lt;/strong&gt;&lt;br&gt;
The practice of configuring a website so AI assistants — ChatGPT, Gemini, Perplexity — can discover, read, and recommend it. Different from SEO: targets AI-generated answers, not Google Search rankings. Relevant signals: robots.txt access, structured data, llms.txt, ACP product feeds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: Is AEO the same as GEO (Generative Engine Optimization)?&lt;/strong&gt;&lt;br&gt;
Largely yes — both terms describe optimization for AI-generated results. AEO is used primarily in the eCommerce context; GEO is more common in content publishing. The underlying signals are the same.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;OAI-SearchBot&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://platform.openai.com/docs/bots" rel="noopener noreferrer"&gt;OpenAI's live search crawler&lt;/a&gt;. Used when ChatGPT answers real-time queries. Respects robots.txt. Must be explicitly allowed — default Magento robots.txt blocks it via wildcard.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: Is OAI-SearchBot the same as GPTBot?&lt;/strong&gt;&lt;br&gt;
No. OAI-SearchBot is for live query answering. GPTBot is for training data collection. Blocking GPTBot has no effect on ChatGPT Shopping visibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;ACP — Agentic Commerce Protocol&lt;/strong&gt;&lt;br&gt;
OpenAI's open standard for structured merchant product data. Defines a &lt;code&gt;.jsonl.gz&lt;/code&gt; feed format submitted at &lt;code&gt;chatgpt.com/merchants&lt;/code&gt; — required for ChatGPT product results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;llms.txt&lt;/strong&gt;&lt;br&gt;
A plain-text file at &lt;code&gt;yourstore.com/llms.txt&lt;/code&gt; — a structured map of your catalog for AI systems. Spec at &lt;a href="https://llmstxt.org/" rel="noopener noreferrer"&gt;llmstxt.org&lt;/a&gt;. Similar to &lt;code&gt;sitemap.xml&lt;/code&gt;, but optimized for AI consumption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;offers.availability&lt;/strong&gt;&lt;br&gt;
A required field in &lt;a href="https://schema.org/Product" rel="noopener noreferrer"&gt;Product JSON-LD schema&lt;/a&gt;. Tells AI systems whether a product is in stock. Value: &lt;code&gt;https://schema.org/InStock&lt;/code&gt; or &lt;code&gt;https://schema.org/OutOfStock&lt;/code&gt;. Missing on most default Magento installations — its absence fails ChatGPT Shopping conformance checks.&lt;/p&gt;


&lt;h2&gt;
  
  
  AEO vs SEO: what's different
&lt;/h2&gt;

&lt;p&gt;SEO gets your store ranked in Google's link list. AEO gets your store cited in AI-generated answers.&lt;/p&gt;

&lt;p&gt;Google reads keywords, backlinks, and page authority. AI systems read:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;robots.txt&lt;/strong&gt; — can AI crawlers access your store at all?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;llms.txt&lt;/strong&gt; — is there a structured map of your catalog?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product JSON-LD schema&lt;/strong&gt; — can AI read prices, availability, and product details?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACP product feed&lt;/strong&gt; — have you registered with OpenAI's merchant program?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these don't exist on a default Magento 2 install — not because Magento is broken, but because it was built before AI search existed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: Does a store with good SEO automatically have good AEO?&lt;/strong&gt;&lt;br&gt;
No. Most signals don't overlap. A store can rank on page one of Google and still score near zero on AI product feed and &lt;code&gt;llms.txt&lt;/code&gt; — because those signals didn't exist when the store was built.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Helps SEO&lt;/th&gt;
&lt;th&gt;Helps AEO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;robots.txt AI bot access&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llms.txt / llms.jsonl&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product JSON-LD schema&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FAQPage schema&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ACP product feed&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemap.xml&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Graph tags&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canonical tags&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  The 9 AEO signals for Magento 2
&lt;/h2&gt;

&lt;p&gt;Run the free audit to see your current score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-aeo-audit
bin/magento setup:upgrade
bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;About the weights below:&lt;/strong&gt; each signal has a weight (0.5–1.0) reflecting its relative impact on overall AEO score. Critical signals (robots.txt, schema, feed) are weight 1.0; supporting signals are lower. Failing a 1.0-weighted signal alone can drop you below the 50% threshold.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Signal #1 — robots.txt: AI Bot Access &lt;em&gt;(weight 1.0)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The most common reason for complete AI invisibility. Magento's default &lt;code&gt;robots.txt&lt;/code&gt; uses a wildcard rule (&lt;code&gt;User-agent: *&lt;/code&gt;) combined with restrictive &lt;code&gt;Disallow&lt;/code&gt; directives. Since AI crawlers like &lt;code&gt;OAI-SearchBot&lt;/code&gt;, &lt;code&gt;GPTBot&lt;/code&gt;, and &lt;code&gt;PerplexityBot&lt;/code&gt; aren't explicitly listed, they inherit those restrictions and get blocked unintentionally.&lt;/p&gt;

&lt;p&gt;Per &lt;a href="https://platform.openai.com/docs/bots" rel="noopener noreferrer"&gt;OpenAI's crawler documentation&lt;/a&gt;, stores that block OAI-SearchBot may significantly limit or prevent visibility in ChatGPT search results.&lt;/p&gt;

&lt;p&gt;This is the most frequently failing signal across all store sizes — and the cheapest to fix.&lt;/p&gt;

&lt;p&gt;Check your file at &lt;code&gt;yourstore.com/robots.txt&lt;/code&gt;. You need these entries, placed &lt;strong&gt;before&lt;/strong&gt; any wildcard block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;OAI&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;GPTBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;PerplexityBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Google&lt;/span&gt;-&lt;span class="n"&gt;Extended&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;ClaudeBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick fix — two options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A: edit &lt;code&gt;robots.txt&lt;/code&gt; manually&lt;/strong&gt; in your Magento admin (Stores → Configuration → Design → Search Engine Robots) or directly in the file. Make sure your edits actually persist (see the nginx warning below).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option B: install a module that injects and validates the rules:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-robots-txt-aeo
bin/magento setup:upgrade &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bin/magento cache:flush
bin/magento angeo:robots:validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Adobe Commerce Cloud:&lt;/strong&gt; robots.txt is served via Fastly VCL. After any change — purge Fastly cache and verify the live file, not the admin config.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Signal #2 — llms.txt: AI Content Map &lt;em&gt;(weight 1.0)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://angeo.dev/how-to-generate-llms-txt-for-magento-2-in-5-minutes/" rel="noopener noreferrer"&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/a&gt; is a plain-text file at &lt;code&gt;yourstore.com/llms.txt&lt;/code&gt; — a structured map of your catalog: categories, key products, CMS pages, currency, language. Defined at &lt;a href="https://llmstxt.org/" rel="noopener noreferrer"&gt;llmstxt.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Perplexity's background indexer actively reads it. For ChatGPT Shopping, it supplements the ACP product feed.&lt;/p&gt;

&lt;p&gt;You can hand-write &lt;code&gt;llms.txt&lt;/code&gt; for a small catalog (the format is just markdown), but for stores with hundreds+ of products it gets stale fast. A common automation approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-llms-txt
bin/magento setup:upgrade
bin/magento angeo:llms:generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also generates &lt;code&gt;llms.jsonl&lt;/code&gt; — the machine-readable sibling. Enable cron for automatic regeneration when your catalog changes.&lt;/p&gt;

&lt;p&gt;→ Deep dive: &lt;a href="https://angeo.dev/how-to-generate-llms-txt-for-magento-2-in-5-minutes/" rel="noopener noreferrer"&gt;How to generate llms.txt for Magento 2 in 5 minutes&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Signal #3 — Product JSON-LD Schema &lt;em&gt;(weight 1.0)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Magento's default Luma theme outputs basic &lt;a href="https://schema.org/Product" rel="noopener noreferrer"&gt;Product schema&lt;/a&gt; but almost always omits &lt;code&gt;offers.availability&lt;/code&gt; — a key field for ChatGPT Shopping conformance. Submissions without it commonly fail validation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: Does Hyvä theme fix the schema problem automatically?&lt;/strong&gt;&lt;br&gt;
Partially. Hyvä has better schema defaults than Luma but still requires explicit configuration for &lt;code&gt;offers.availability&lt;/code&gt; and variant-level data. Neither platform handles this out of the box — a dedicated module or theme override is required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quick check on any product page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/sample-product | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'"availability":"[^"]*"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can fix this either via a custom theme override or with a module. Example using a module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-rich-data
bin/magento setup:upgrade &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bin/magento cache:flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds: &lt;code&gt;offers.availability&lt;/code&gt; (real-time stock), &lt;code&gt;aggregateRating&lt;/code&gt;, &lt;code&gt;BreadcrumbList&lt;/code&gt;. It also covers Signal #5 — FAQPage schema on CMS pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 4 most common schema failures I see (in order of frequency):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Missing &lt;code&gt;offers.availability&lt;/code&gt;&lt;/strong&gt; — 90%+ of default Magento stores. Without it, ChatGPT Shopping conformance fails outright.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variant-level data flattened&lt;/strong&gt; — configurable products lose &lt;code&gt;variesBy&lt;/code&gt; data when serialized. ChatGPT shows "out of stock" even when 6 of 8 variants are available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyvä strips microdata&lt;/strong&gt; — performance optimization removes JSON-LD entirely. Needs a layout XML override to re-inject.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrong availability values&lt;/strong&gt; — using &lt;code&gt;"InStock"&lt;/code&gt; (string) instead of &lt;code&gt;"https://schema.org/InStock"&lt;/code&gt; (URI). Validators accept it, AI engines silently drop it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your audit shows Signal #3 failing, run this diagnostic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with any product URL from your store&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/sample-product | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 20 &lt;span class="s1"&gt;'application/ld+json'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'availability|priceCurrency|sku'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;availability&lt;/code&gt; is missing or doesn't start with &lt;code&gt;https://schema.org/&lt;/code&gt;, that's your problem.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example — Magento 2 store, home goods, ~2,400 SKUs
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Before — default install:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AEO score: &lt;strong&gt;23%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✗ robots.txt — OAI-SearchBot blocked&lt;/li&gt;
&lt;li&gt;✗ llms.txt — not found&lt;/li&gt;
&lt;li&gt;✗ Product schema — no availability&lt;/li&gt;
&lt;li&gt;✗ AI product feed — not registered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ After — 90 minutes later:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AEO score: &lt;strong&gt;84%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✓ robots.txt — 7 AI bots allowed&lt;/li&gt;
&lt;li&gt;✓ llms.txt — 2,400 products mapped&lt;/li&gt;
&lt;li&gt;✓ Product schema — availability live&lt;/li&gt;
&lt;li&gt;◷ Feed — submitted, pending approval&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;At this point — after signals #1, #2, and #3 — most stores jump from low-twenties into the 50–60% range.&lt;/strong&gt; Run the audit again to confirm your progress before continuing:&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Signal #4 — AI Product Feed / ChatGPT Shopping &lt;em&gt;(weight 1.0)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;ChatGPT Shopping requires a registered ACP product feed. Without it, products are unlikely to appear in ChatGPT Shopping results regardless of other signals. The feed is &lt;code&gt;.jsonl.gz&lt;/code&gt;, submitted to a private SFTP endpoint provided by OpenAI after approval, refreshed every 15 minutes.&lt;/p&gt;

&lt;p&gt;Building an ACP feed from scratch is doable but non-trivial — you need to handle JSONL streaming, gzip compression, SFTP auth, the &lt;code&gt;offers.availability&lt;/code&gt; mapping, and 15-minute refresh cron. Most teams either build it in-house or use a module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-openai-product-feed &lt;span class="se"&gt;\&lt;/span&gt;
  angeo/module-openai-product-feed-api
bin/magento setup:upgrade
bin/magento angeo:aeo:feed:generate
bin/magento angeo:aeo:feed:validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply at &lt;code&gt;chatgpt.com/merchants&lt;/code&gt;. Currently US-only and waitlisted. After approval, set up 15-minute cron — stale availability data is the #1 reason for post-approval suppression.&lt;/p&gt;

&lt;p&gt;→ Deep dive: &lt;a href="https://angeo.dev/magento-2-chatgpt-shopping-registration/" rel="noopener noreferrer"&gt;How to Register Your Magento 2 Store for ChatGPT Shopping&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Does this actually move the needle?
&lt;/h2&gt;

&lt;p&gt;Fair question — and the honest answer is "yes, but unevenly across platforms."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Perplexity&lt;/strong&gt; shows the fastest impact. Background re-indexing typically picks up &lt;code&gt;llms.txt&lt;/code&gt; and schema changes within days to a few weeks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT&lt;/strong&gt; is gated by merchant approval. Technical fixes alone won't get you into Shopping results — you also need the feed registered and approved. Once approved, indexing is usually 48–72 hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini&lt;/strong&gt; mostly piggybacks on Google Merchant Center. If you're already there, fixes propagate quickly. If not, getting into Merchant Center is the bigger lift than AEO itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AEO is not instant. But with these signals failing, visibility across all three engines is close to zero — fixing them is the floor, not the ceiling.&lt;/p&gt;




&lt;h3&gt;
  
  
  Signals #5–#9 — Supporting Signals
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;FAQPage schema&lt;/strong&gt; &lt;em&gt;(weight 0.5)&lt;/em&gt;&lt;br&gt;
Increases citation probability for answer-style AI queries. Injected automatically alongside Product schema on CMS pages. Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; yourstore.com | &lt;span class="nb"&gt;grep &lt;/span&gt;FAQPage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;sitemap.xml&lt;/strong&gt; &lt;em&gt;(weight 0.8)&lt;/em&gt;&lt;br&gt;
AI crawlers use sitemap.xml to discover your full catalog. Enable in Magento admin: &lt;strong&gt;Stores → Config → Catalog → XML Sitemap&lt;/strong&gt;. Submit to Google Search Console — also surfaces to &lt;code&gt;Google-Extended&lt;/code&gt; (Gemini).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open Graph tags&lt;/strong&gt; &lt;em&gt;(weight 0.7)&lt;/em&gt;&lt;br&gt;
&lt;code&gt;og:title&lt;/code&gt;, &lt;code&gt;og:description&lt;/code&gt;, &lt;code&gt;og:image&lt;/code&gt; — used as content fallback when structured schema is absent. Most Magento themes include these by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canonical tags&lt;/strong&gt; &lt;em&gt;(weight 0.6)&lt;/em&gt;&lt;br&gt;
Prevents AI systems from indexing Magento's multiple URL variants. Enable: &lt;strong&gt;Stores → Config → Catalog → SEO → Use Canonical Link Meta Tag For Products/Categories&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Magento has no canonical option for the homepage — this is expected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;llms.jsonl&lt;/strong&gt; &lt;em&gt;(weight 0.75)&lt;/em&gt;&lt;br&gt;
Machine-readable catalog at &lt;code&gt;yourstore.com/llms.jsonl&lt;/code&gt;. One JSON object per product per line. Used by AI pipelines for vector indexing. Generated automatically by &lt;code&gt;angeo/module-llms-txt&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  ChatGPT vs Perplexity vs Gemini: how each AI discovers products
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt; — hybrid approach: trained knowledge + live search via &lt;code&gt;OAI-SearchBot&lt;/code&gt; + ACP merchant product feed. Requires merchant registration. Feed is the authoritative source for product data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perplexity&lt;/strong&gt; — real-time answer engine. Always cites sources with links. &lt;code&gt;PerplexityBot&lt;/code&gt; actively reads &lt;code&gt;llms.txt&lt;/code&gt; — one of the few AI platforms where this has documented crawl value. No separate product feed required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini&lt;/strong&gt; — operates on &lt;a href="https://blog.google/products/shopping/google-shopping-graph/" rel="noopener noreferrer"&gt;Google's Shopping Graph&lt;/a&gt; (50B+ products, updated 2B+ times per hour). Any product in Google Merchant Center is available to Gemini. &lt;code&gt;Google-Extended&lt;/code&gt; is the separate crawler for AI Overviews — allowing it does not affect regular Google Search rankings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheat sheet — what each engine actually reads:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;ChatGPT&lt;/th&gt;
&lt;th&gt;Perplexity&lt;/th&gt;
&lt;th&gt;Gemini&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ACP product feed&lt;/td&gt;
&lt;td&gt;✅ primary&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAI-SearchBot crawl&lt;/td&gt;
&lt;td&gt;✅ secondary&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llms.txt&lt;/td&gt;
&lt;td&gt;⚠️ untested&lt;/td&gt;
&lt;td&gt;✅ documented&lt;/td&gt;
&lt;td&gt;⚠️ untested&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product JSON-LD&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ via Shopping Graph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Merchant Center&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✅ primary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Graph tags&lt;/td&gt;
&lt;td&gt;✅ fallback&lt;/td&gt;
&lt;td&gt;✅ fallback&lt;/td&gt;
&lt;td&gt;✅ fallback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;robots.txt&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;OAI-SearchBot&lt;/code&gt;, &lt;code&gt;GPTBot&lt;/code&gt;, &lt;code&gt;ChatGPT-User&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PerplexityBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Google-Extended&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern: ChatGPT prefers structured submissions (the feed), Perplexity prefers crawl-discoverable structure (llms.txt + schema), Gemini piggybacks on Google's existing pipelines (Shopping Graph + Merchant Center). Cover all three and you're visible across the major engines.&lt;/p&gt;


&lt;h2&gt;
  
  
  Score interpretation
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Label&lt;/th&gt;
&lt;th&gt;Typical situation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;0–25%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Needs Improvement&lt;/td&gt;
&lt;td&gt;Default Magento install. AI crawlers blocked.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;26–50%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Needs Improvement&lt;/td&gt;
&lt;td&gt;Some fixes applied. Schema or feed still missing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;51–75%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Core signals in place. Feed not yet registered.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;76–90%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Strong foundation. Minor schema gaps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;91–100%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Full compliance. Feed registered and live.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Free open-source modules — one per signal
&lt;/h2&gt;

&lt;p&gt;Each AEO signal has a corresponding open-source Magento 2 module. MIT licensed. Install via Composer. Runs on your server — no external API calls, no data sent outside your infrastructure.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&lt;/th&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-aeo-audit&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Diagnostic — checks all 9 signals, score trend dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://packagist.org/packages/angeo/module-robots-txt-aeo" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-robots-txt-aeo&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Signal #1 — injects AI bot rules into robots.txt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://packagist.org/packages/angeo/module-llms-txt" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-llms-txt&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Signals #2, #2b — generates llms.txt and llms.jsonl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://packagist.org/packages/angeo/module-rich-data" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-rich-data&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Signals #3, #5 — Product JSON-LD + FAQPage schema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://packagist.org/packages/angeo/module-openai-product-feed" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-openai-product-feed&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Signal #4 — ACP product feed for ChatGPT Shopping&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  90-minute implementation checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Baseline audit:&lt;/strong&gt; &lt;code&gt;bin/magento angeo:aeo:audit&lt;/code&gt; — note your starting score&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix robots.txt:&lt;/strong&gt; &lt;code&gt;composer require angeo/module-robots-txt-aeo&lt;/code&gt; → validate with &lt;code&gt;angeo:robots:validate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate llms.txt:&lt;/strong&gt; &lt;code&gt;composer require angeo/module-llms-txt&lt;/code&gt; → &lt;code&gt;angeo:llms:generate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix Product schema:&lt;/strong&gt; &lt;code&gt;composer require angeo/module-rich-data&lt;/code&gt; → verify &lt;code&gt;offers.availability&lt;/code&gt; in page source&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable sitemap:&lt;/strong&gt; Stores → Config → Catalog → XML Sitemap → Enable → submit to Search Console&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate product feed:&lt;/strong&gt; &lt;code&gt;composer require angeo/module-openai-product-feed angeo/module-openai-product-feed-api&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply for ChatGPT Shopping:&lt;/strong&gt; configure seller name + policy URLs → apply at &lt;code&gt;chatgpt.com/merchants&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final audit:&lt;/strong&gt; &lt;code&gt;bin/magento angeo:aeo:audit&lt;/code&gt; → target 80%+&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Adobe Commerce Cloud: additional steps
&lt;/h2&gt;

&lt;p&gt;Adobe Commerce Cloud adds one complication — Fastly CDN. robots.txt is stored in &lt;code&gt;pub/media/&lt;/code&gt; and served via a Fastly VCL snippet. After any robots.txt change:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save in Magento admin&lt;/li&gt;
&lt;li&gt;Purge Fastly cache&lt;/li&gt;
&lt;li&gt;Verify the live file at &lt;code&gt;yourstore.com/robots.txt&lt;/code&gt; — not the admin config&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fastly also caches product pages. If availability changes but Fastly serves a stale page, &lt;code&gt;OAI-SearchBot&lt;/code&gt; reads incorrect stock data — leading to product suppression after ChatGPT Shopping approval. Use the 15-minute cron for the ACP product feed as the authoritative source for availability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adobe Commerce vs Magento Open Source — AEO-relevant differences:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open Source:&lt;/strong&gt; robots.txt is editable directly, cron is yours, no Fastly cache layer to invalidate. AEO setup is straightforward.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adobe Commerce Cloud:&lt;/strong&gt; Fastly is mandatory, robots.txt is served via VCL, cron has timing constraints. Every AEO change needs an extra "purge Fastly" step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B2B Commerce on Adobe Commerce:&lt;/strong&gt; customer-group pricing breaks ACP feed assumptions (the protocol expects single price per SKU). You'll need a separate "public" feed with B2C pricing for ChatGPT Shopping. Don't expose B2B pricing to AI engines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're on Adobe Commerce Cloud, expect implementation to take 2-3x longer than vanilla Magento — most of the extra time is fighting Fastly cache TTLs, not AEO logic itself.&lt;/p&gt;


&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Does AEO replace SEO for Magento stores?
&lt;/h3&gt;

&lt;p&gt;No. They target different channels. SEO gets you ranked in Google Search. AEO gets you cited in AI-generated answers. A store with strong SEO can still score very low on AEO by default — because the signals are completely different.&lt;/p&gt;
&lt;h3&gt;
  
  
  Is ChatGPT Shopping free for merchants?
&lt;/h3&gt;

&lt;p&gt;Product discovery is currently organic — no cost to appear in results. No transaction fees on purchases that start in ChatGPT as of April 2026. Onboarding is US-only and waitlisted.&lt;/p&gt;
&lt;h3&gt;
  
  
  How long before results are visible after fixing AEO?
&lt;/h3&gt;

&lt;p&gt;Technical fixes take effect as AI crawlers re-index your pages: 1–3 weeks for Perplexity, 2–6 weeks for Google-Extended, 48–72 hours after ChatGPT Shopping approval for the feed layer.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is GPTBot vs OAI-SearchBot?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;GPTBot&lt;/code&gt; is OpenAI's training crawler. Blocking it opts your content out of GPT model training but has no effect on ChatGPT Shopping visibility. &lt;code&gt;OAI-SearchBot&lt;/code&gt; is the live search crawler — this one must be allowed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Does this work with Hyvä theme?
&lt;/h3&gt;

&lt;p&gt;Yes. All Angeo modules are compatible with Magento Open Source and Adobe Commerce on both Luma and Hyvä themes. PHP 8.2+ required.&lt;/p&gt;


&lt;h2&gt;
  
  
  Start here
&lt;/h2&gt;

&lt;p&gt;Run the audit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your score is below 50%, your store is likely invisible to AI assistants today. Fixing the first 3 signals (robots.txt, llms.txt, Product schema) usually gets you most of the way there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;Install CLI Audit&lt;/a&gt; — MIT-licensed, runs on your server, no telemetry&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angeo.dev/ai-magento-audit/" rel="noopener noreferrer"&gt;Free Web Self-Assessment&lt;/a&gt; — no install required, runs against your live site&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Related posts in this series
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angeo.dev/how-to-generate-llms-txt-for-magento-2-in-5-minutes/" rel="noopener noreferrer"&gt;How to generate llms.txt for Magento 2 in 5 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angeo.dev/magento-2-chatgpt-shopping-registration/" rel="noopener noreferrer"&gt;How to Register Your Magento 2 Store for ChatGPT Shopping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Product Schema FAIL in Magento 2 AEO Audit — How to Fix It&lt;/em&gt; (publishing soon)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Perplexity vs ChatGPT vs Gemini: How Each AI Discovers Your Products&lt;/em&gt; (publishing soon)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Adobe Commerce vs Magento Open Source: AI Visibility in 2026&lt;/em&gt; (publishing soon)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow me here on DEV to get the next 3 deep-dives when they ship — or subscribe at &lt;a href="https://angeo.dev" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt; for the full series.&lt;/p&gt;




&lt;p&gt;What's your AEO score? Have you registered with ChatGPT Shopping yet? Drop a comment — I'll do a deeper dive on whichever signal trips up the most stores in the discussion.&lt;/p&gt;

&lt;p&gt;If you're working on similar problems on other platforms (Shopware, WooCommerce, BigCommerce, custom storefronts), the framework here mostly transfers — the implementation details differ, but the 9 signals are platform-agnostic. Curious what the equivalents look like in your stack.&lt;/p&gt;

</description>
      <category>magento</category>
      <category>ai</category>
      <category>ecommerce</category>
      <category>webdev</category>
    </item>
    <item>
      <title>llms.txt for Magento 2: What It Is, Why It Matters, and How to Generate It in 5 Minutes</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Fri, 24 Apr 2026 04:48:48 +0000</pubDate>
      <link>https://dev.to/angeo/llmstxt-for-magento-2-what-it-is-why-it-matters-and-how-to-generate-it-in-5-minutes-58fi</link>
      <guid>https://dev.to/angeo/llmstxt-for-magento-2-what-it-is-why-it-matters-and-how-to-generate-it-in-5-minutes-58fi</guid>
      <description>&lt;p&gt;Google has &lt;code&gt;robots.txt&lt;/code&gt;. Google has &lt;code&gt;sitemap.xml&lt;/code&gt;. Now AI assistants have &lt;code&gt;llms.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you run a Magento 2 store and haven't heard of &lt;code&gt;llms.txt&lt;/code&gt; yet — this post is the 5-minute version of everything you need to know, plus the exact commands to generate it today.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem: AI assistants don't crawl like Google does
&lt;/h2&gt;

&lt;p&gt;When Google indexes your store, its crawler visits thousands of pages and builds a picture of your catalog over weeks. It's slow, but it works.&lt;/p&gt;

&lt;p&gt;ChatGPT, Claude, and Perplexity operate differently. When a user asks &lt;em&gt;"what's a good blender under $150?"&lt;/em&gt;, the AI doesn't crawl your store in real time. It works from what it already knows — or from a structured snapshot it can parse in milliseconds.&lt;/p&gt;

&lt;p&gt;If you haven't given it that snapshot, it either ignores your store or gets the details wrong: outdated prices, discontinued products, categories that no longer exist.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is that snapshot.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is llms.txt?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is a plain-text file hosted at the root of your domain — &lt;code&gt;yourstore.com/llms.txt&lt;/code&gt; — that gives AI systems a structured, human-readable summary of your store.&lt;/p&gt;

&lt;p&gt;Think of it as a &lt;code&gt;README.md&lt;/code&gt; for your entire eCommerce site. It tells AI assistants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What your store sells&lt;/li&gt;
&lt;li&gt;What categories exist&lt;/li&gt;
&lt;li&gt;Key product URLs and descriptions&lt;/li&gt;
&lt;li&gt;CMS pages (shipping, returns, about)&lt;/li&gt;
&lt;li&gt;Store metadata: name, currency, language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A minimal example looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Store: Volta Equipment&lt;/span&gt;

&lt;span class="gu"&gt;## STORE&lt;/span&gt;
Name: Volta Equipment
URL: https://voltaequipment.com/
Currency: USD

&lt;span class="gu"&gt;### CATEGORIES ###&lt;/span&gt;
Category ID: 4
Name: Fitness Equipment
URL: https://voltaequipment.com/fitness
Description: Commercial and home gym equipment

&lt;span class="gu"&gt;### PRODUCTS ###&lt;/span&gt;
SKU: VE-KB32
Name: 32kg Kettlebell — Cast Iron
Price: 8900
URL: https://voltaequipment.com/32kg-kettlebell
Short Description: Competition-grade cast iron kettlebell, powder-coated finish

&lt;span class="gu"&gt;## CMS PAGES&lt;/span&gt;
TYPE: PAGE
TITLE: Shipping Policy
URL: https://voltaequipment.com/shipping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple. No JSON schema. No special syntax. Just structured plain text that both AI systems and humans can read instantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Does llms.txt actually work?
&lt;/h2&gt;

&lt;p&gt;Fair question — and the honest answer is: &lt;strong&gt;it depends on the AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some AI systems (Perplexity, some Claude configurations) actively read &lt;code&gt;llms.txt&lt;/code&gt; when crawling. Others, like GPTBot, primarily rely on the page content itself and Product schema JSON-LD. OpenAI has not yet published an official spec for &lt;code&gt;llms.txt&lt;/code&gt; consumption.&lt;/p&gt;

&lt;p&gt;So why generate it at all?&lt;/p&gt;

&lt;p&gt;Three reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. It costs nothing to add.&lt;/strong&gt; One Composer command and it's live. There's no downside.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It's a trust signal.&lt;/strong&gt; When a Magento developer or agency reviews your AEO setup, a present &lt;code&gt;llms.txt&lt;/code&gt; signals you're thinking about AI visibility — and it's one of the 8 signals checked by the &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;AEO audit module&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The standard is evolving fast.&lt;/strong&gt; OpenAI, Anthropic, and Google are all moving toward structured merchant data formats. Stores with &lt;code&gt;llms.txt&lt;/code&gt; already in place will require zero additional work when these systems formalize their specs. Stores without it will have to catch up.&lt;/p&gt;




&lt;h2&gt;
  
  
  llms.txt vs llms.jsonl — what's the difference?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;angeo/module-llms-txt&lt;/code&gt; module generates both files. Here's when each matters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Plain text&lt;/td&gt;
&lt;td&gt;AI assistants reading store context, Perplexity, Claude&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;llms.jsonl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSON Lines&lt;/td&gt;
&lt;td&gt;Structured product data, future ACP integrations, developers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;llms.jsonl&lt;/code&gt; is the machine-readable sibling — one JSON object per product, per line, compressed for fast parsing. If you're planning to integrate with OpenAI's ACP feed later, &lt;code&gt;llms.jsonl&lt;/code&gt; is the stepping stone.&lt;/p&gt;

&lt;p&gt;For now, generate both. They serve different consumers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation: 3 commands
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-llms-txt
bin/magento setup:upgrade
bin/magento cache:flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The module is MIT licensed, free on &lt;a href="https://packagist.org/packages/angeo/module-llms-txt" rel="noopener noreferrer"&gt;Packagist&lt;/a&gt;, and runs entirely on your server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Generate the files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Option A — CLI (recommended)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:llms:generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates both &lt;code&gt;llms.txt&lt;/code&gt; and &lt;code&gt;llms.jsonl&lt;/code&gt; at your store root and outputs the file paths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option B — Magento Admin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;Stores → Configuration → General → Angeo → LLMS&lt;/strong&gt; and trigger manual generation from the backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option C — Cron (for automatic updates)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The module registers a Magento cron job. As long as your server cron is running, the files stay current:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento cron:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For stores with frequently changing inventory — new products, price updates, seasonal categories — cron is the right default.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verify it's live
&lt;/h2&gt;

&lt;p&gt;After generation, open &lt;code&gt;yourstore.com/llms.txt&lt;/code&gt; in a browser. You should see your store name, category list, and product entries.&lt;/p&gt;

&lt;p&gt;Then run the AEO audit to confirm it passes signal #2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ PASS  robots.txt — OAI-SearchBot and GPTBot allowed
✓ PASS  llms.txt — store content map present
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;llms.txt&lt;/code&gt; shows &lt;code&gt;FAIL&lt;/code&gt;, check that the file exists at &lt;code&gt;pub/llms.txt&lt;/code&gt; and that your web server is serving it correctly (not blocked by nginx or a CDN rule).&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-store support
&lt;/h2&gt;

&lt;p&gt;If you're running multiple store views or storefronts, the module generates separate &lt;code&gt;llms.txt&lt;/code&gt; files per store — each with the correct currency, language, and URL structure. No additional configuration needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to do after llms.txt
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is AEO signal #2. To complete your AI visibility setup, the remaining signals are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ &lt;code&gt;robots.txt&lt;/code&gt; — Allow OAI-SearchBot, GPTBot, ClaudeBot, and 4 others&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;llms.txt&lt;/code&gt; — structured store map ← &lt;strong&gt;you are here&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;→ &lt;code&gt;Product Schema&lt;/code&gt; — JSON-LD with &lt;code&gt;offers.availability&lt;/code&gt; on every product page&lt;/li&gt;
&lt;li&gt;→ &lt;code&gt;AI Product Feed&lt;/code&gt; — ACP-compliant &lt;code&gt;.jsonl.gz&lt;/code&gt; for ChatGPT Shopping registration&lt;/li&gt;
&lt;li&gt;→ &lt;code&gt;FAQPage Schema&lt;/code&gt; — structured Q&amp;amp;A for policy pages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run &lt;code&gt;bin/magento angeo:aeo:audit&lt;/code&gt; to see your current score across all 8 signals.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;llms.txt&lt;/code&gt; gives AI assistants a structured snapshot of your store&lt;/li&gt;
&lt;li&gt;It's served at &lt;code&gt;yourstore.com/llms.txt&lt;/code&gt; — same pattern as &lt;code&gt;robots.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;angeo/module-llms-txt&lt;/code&gt; module generates it automatically, with cron support&lt;/li&gt;
&lt;li&gt;It takes 3 commands and under 5 minutes to set up&lt;/li&gt;
&lt;li&gt;It's one of 8 AEO signals that determine your visibility in ChatGPT, Claude, and Perplexity&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Free modules used in this post:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-llms-txt" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-llms-txt&lt;/code&gt;&lt;/a&gt; — generates llms.txt and llms.jsonl&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-aeo-audit&lt;/code&gt;&lt;/a&gt; — checks all 8 AEO signals via CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://angeo.dev/ai-magento-audit/" rel="noopener noreferrer"&gt;&lt;strong&gt;Run a free AEO audit on your store →&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>aeo</category>
      <category>ai</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>How to Register Your Magento 2 Store for ChatGPT Shopping (ACP Feed + Step-by-Step)</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Mon, 20 Apr 2026 17:20:06 +0000</pubDate>
      <link>https://dev.to/angeo/how-to-register-your-magento-2-store-for-chatgpt-shopping-acp-feed-step-by-step-58gf</link>
      <guid>https://dev.to/angeo/how-to-register-your-magento-2-store-for-chatgpt-shopping-acp-feed-step-by-step-58gf</guid>
      <description>&lt;p&gt;ChatGPT now processes over &lt;strong&gt;50 million shopping queries per day&lt;/strong&gt;. Appearing in those results is not automatic — it requires a deliberate application process, a spec-compliant product feed, and passing OpenAI's conformance checks.&lt;/p&gt;

&lt;p&gt;This guide walks through the entire process: from the pre-check that determines if your store is ready, to the merchant application, to the ongoing cron setup that keeps your feed current.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Shopify and Etsy merchants&lt;/strong&gt; already have native integrations. This guide is for &lt;strong&gt;Magento 2 / Adobe Commerce&lt;/strong&gt; stores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🔗 Originally published on &lt;a href="https://angeo.dev/magento-2-chatgpt-shopping-registration/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9qglgqzizrue23usaeu.png" alt="How to Prepare Your Magento 2 Store for ChatGPT Shopping" width="800" height="533"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Before You Apply: The Pre-Check
&lt;/h2&gt;

&lt;p&gt;OpenAI's conformance checks verify technical requirements before granting production access. Stores that fail the pre-check go into a review queue and receive vague rejection emails. Do the pre-check yourself first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output before you start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ PASS  robots.txt — OAI-SearchBot and GPTBot allowed
✓ PASS  llms.txt — store content map present
✓ PASS  Product Schema — JSON-LD with offers.availability
✗ FAIL  AI Product Feed — no feed found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Signal &lt;strong&gt;#5 (AI Product Feed)&lt;/strong&gt; will fail until Step 1 below. Signals &lt;strong&gt;#1, #2, and #3 must all PASS&lt;/strong&gt; before applying at chatgpt.com/merchants.&lt;/p&gt;

&lt;p&gt;If robots.txt is failing — most default Magento 2 installs have a &lt;code&gt;User-agent: *&lt;/code&gt; wildcard that silently blocks &lt;code&gt;OAI-SearchBot&lt;/code&gt;. Fix that first. It's a hard gate that invalidates everything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Install the product feed modules
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-openai-product-feed &lt;span class="se"&gt;\&lt;/span&gt;
  angeo/module-openai-product-feed-api

bin/magento setup:upgrade
bin/magento cache:flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both modules are MIT licensed, free on Packagist. No license keys, no SaaS — runs entirely on your server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Configure seller information
&lt;/h2&gt;

&lt;p&gt;Go to &lt;strong&gt;Stores → Configuration → Angeo → Product Feed API&lt;/strong&gt; and fill in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Seller name&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target country&lt;/strong&gt; — ISO 3166 two-letter code (e.g. &lt;code&gt;US&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy URLs&lt;/strong&gt; — privacy policy, returns, shipping, terms of service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These populate &lt;code&gt;seller.links&lt;/code&gt; on every product record. They are merchant credibility signals in OpenAI's scoring. Missing policy URLs is a common reason for suppressed products after initial approval.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Generate and validate the feed
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate the feed file&lt;/span&gt;
bin/magento angeo:aeo:feed:generate

&lt;span class="c"&gt;# Validate structure and required fields&lt;/span&gt;
bin/magento angeo:aeo:feed:validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm in the output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each product has a &lt;code&gt;variants&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;Prices are in minor units (see the price format section below)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;availability.status&lt;/code&gt; is present on every product&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;seller.links&lt;/code&gt; has at least two policy URLs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4 — Verify promotions output
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/magento angeo:aeo:feed:validate &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;promotions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Active Magento cart price rules should appear automatically as ACP promotions with &lt;code&gt;active_period&lt;/code&gt;, &lt;code&gt;benefits&lt;/code&gt;, and &lt;code&gt;status: "active"&lt;/code&gt;. If promotions are missing here, they won't appear in ChatGPT results either.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Apply at chatgpt.com/merchants
&lt;/h2&gt;

&lt;p&gt;Submit your store URL and business details. OpenAI tests schema compliance, HTTP response codes, and feed integrity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current status:&lt;/strong&gt; Onboarding is US-only and available to approved partners — expect a waitlist. Application review typically takes 1–2 weeks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Receive SFTP endpoint and push the feed
&lt;/h2&gt;

&lt;p&gt;After approval, OpenAI provides a &lt;strong&gt;private SFTP endpoint&lt;/strong&gt; for your store. Push your &lt;code&gt;.jsonl.gz&lt;/code&gt; feed file to this endpoint.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Do &lt;strong&gt;not&lt;/strong&gt; host the feed publicly on your website. The feed goes to the private SFTP endpoint OpenAI provides — not a public REST endpoint on your store. Submit a sample first; after it passes validation, push the full catalog.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 7 — Set up 15-minute cron
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# crontab — every 15 minutes&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt;/15 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/bin/php /var/www/html/bin/magento angeo:aeo:feed:generate &lt;span class="nt"&gt;--push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenAI accepts feed refreshes every 15 minutes. Full feed re-submission is required each time — there is currently no incremental update support.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Most common post-approval failure:&lt;/strong&gt; Stale availability data — out-of-stock products showing as available — is the #1 reason products get suppressed after initial approval. The 15-minute cron prevents this.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Feed Format: What OpenAI Actually Accepts
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Extension&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JSON Lines&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.jsonl.gz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recommended. One product object per line. Handles nested variants cleanly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.csv.gz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Works for flat catalogs. Variant structures need to be flattened.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; TSV and XML were in OpenAI's original spec announcement but have since been removed. Always check the &lt;a href="https://developers.openai.com/commerce/specs/feed/" rel="noopener noreferrer"&gt;official feed spec&lt;/a&gt; for the current list.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Price Format Trap
&lt;/h2&gt;

&lt;p&gt;This is the &lt;strong&gt;single most common implementation error&lt;/strong&gt; across all ACP integrations.&lt;/p&gt;

&lt;p&gt;Price must be sent in &lt;strong&gt;ISO 4217 minor units as an integer&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;❌&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Wrong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fails&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;validation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;14.99&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"14.99"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Correct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;minor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;units&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1499&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;€&lt;/span&gt;&lt;span class="mf"&gt;14.99&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14900&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mf"&gt;149.00&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The module handles this automatically: &lt;code&gt;(int) round($price * 100)&lt;/code&gt;. But if you are building a custom integration or mapping from a Google Shopping feed — check this field first. The validation error message for a wrong price format is non-obvious.&lt;/p&gt;




&lt;h2&gt;
  
  
  What OpenAI's Conformance Check Validates
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;What it verifies&lt;/th&gt;
&lt;th&gt;Handled by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feed schema&lt;/td&gt;
&lt;td&gt;Required fields, correct data types, valid URIs&lt;/td&gt;
&lt;td&gt;ProductMapper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price format&lt;/td&gt;
&lt;td&gt;Integer minor units, ISO 4217 currency code&lt;/td&gt;
&lt;td&gt;ProductMapper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Availability flags&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;enable_search&lt;/code&gt; and &lt;code&gt;availability.status&lt;/code&gt; present&lt;/td&gt;
&lt;td&gt;ProductMapper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Promotion schema&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;benefits&lt;/code&gt; array with type, dates, &lt;code&gt;status: "active"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;PromotionMapper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Seller links&lt;/td&gt;
&lt;td&gt;At least 2 policy URLs present&lt;/td&gt;
&lt;td&gt;Admin config → seller.links&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product IDs&lt;/td&gt;
&lt;td&gt;Unique, stable, no duplicates across the feed&lt;/td&gt;
&lt;td&gt;ProductMapper&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  No Fees for Discovery
&lt;/h2&gt;

&lt;p&gt;Product discovery results in ChatGPT are currently &lt;strong&gt;organic and unsponsored&lt;/strong&gt;. There is no cost to submit a product feed or appear in shopping results.&lt;/p&gt;

&lt;p&gt;The 4% transaction fee announced with Instant Checkout applied only to completed in-chat purchases — and OpenAI is moving away from that model toward merchant-owned checkout. As of April 2026, &lt;strong&gt;there are no fees&lt;/strong&gt; on purchases that start in ChatGPT.&lt;/p&gt;

&lt;p&gt;After approval, the feed needs to be indexed — typically &lt;strong&gt;48–72 hours&lt;/strong&gt;. Products with complete Product JSON-LD schema, high availability accuracy, rich descriptions, and active promotions appear first.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checklist Before Submitting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;bin/magento angeo:aeo:audit&lt;/code&gt; — robots.txt, llms.txt, Product schema all &lt;strong&gt;PASS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Feed generates without errors and produces valid &lt;code&gt;.jsonl.gz&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Each product has &lt;code&gt;variants&lt;/code&gt;, correct prices in minor units, &lt;code&gt;availability.status&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Seller info complete: name, country (ISO 3166), at least 2 policy URLs&lt;/li&gt;
&lt;li&gt;[ ] Active promotions appear with &lt;code&gt;status: "active"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] 15-minute cron configured and tested&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;All four Angeo modules are free, MIT licensed, and available on Packagist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-aeo-audit&lt;/code&gt;&lt;/a&gt; — AEO CLI audit, 8 signals&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-llms-txt" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-llms-txt&lt;/code&gt;&lt;/a&gt; — auto-generates llms.txt&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-openai-product-feed" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-openai-product-feed&lt;/code&gt;&lt;/a&gt; — ACP feed generator&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://packagist.org/packages/angeo/module-openai-product-feed-api" rel="noopener noreferrer"&gt;&lt;code&gt;angeo/module-openai-product-feed-api&lt;/code&gt;&lt;/a&gt; — REST API, 6 endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://angeo.dev/ai-magento-audit/" rel="noopener noreferrer"&gt;&lt;strong&gt;Free AEO Self-Assessment →&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>chatgpt</category>
      <category>aeo</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>How to Fix robots.txt for ChatGPT and Gemini in Magento 2 (2026 Update)</title>
      <dc:creator>Ievgenii Gryshkun</dc:creator>
      <pubDate>Thu, 16 Apr 2026 20:41:06 +0000</pubDate>
      <link>https://dev.to/angeo/how-to-fix-robotstxt-for-chatgpt-and-gemini-in-magento-2-4e11</link>
      <guid>https://dev.to/angeo/how-to-fix-robotstxt-for-chatgpt-and-gemini-in-magento-2-4e11</guid>
      <description>&lt;p&gt;Your sitemap is configured. Your Core Web Vitals score is green. Your product catalog is perfectly structured. And yet when a user asks ChatGPT for products you sell, your store doesn't appear.&lt;/p&gt;

&lt;p&gt;Most of the time, the reason is a single file: &lt;code&gt;robots.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Specifically — a &lt;code&gt;robots.txt&lt;/code&gt; written for Google in 2019 and never updated for the ten AI crawlers that now determine your visibility in ChatGPT, Gemini, Claude, and Perplexity.&lt;/p&gt;

&lt;p&gt;🔗 Originally published at &lt;a href="https://angeo.dev/magento-2-robots-txt-chatgpt-gemini-ai-bots/" rel="noopener noreferrer"&gt;angeo.dev/magento-2-robots-txt-chatgpt-gemini-ai-bots&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why robots.txt Is AEO Signal #1
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;angeo/module-aeo-audit&lt;/a&gt; checks robots.txt first and marks it Critical because it is a gate. Every other AEO signal — llms.txt, Product schema, AI product feed — is irrelevant if the AI crawler cannot enter your store.&lt;/p&gt;

&lt;p&gt;OpenAI states this without ambiguity:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Sites that are opted out of OAI-SearchBot will not be shown in ChatGPT search answers."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not "may not appear." &lt;strong&gt;Will not appear.&lt;/strong&gt; If &lt;code&gt;OAI-SearchBot&lt;/code&gt; is blocked — by an explicit Disallow or caught in a wildcard rule — your store is excluded from ChatGPT search answers regardless of everything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Three Types of AI Bots — Why the Difference Matters
&lt;/h2&gt;

&lt;p&gt;Before listing every bot, understand what each one actually does. Conflating them causes the most common robots.txt misconfiguration.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Search &amp;amp; indexing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Builds the live index used when users ask AI questions. Cites sources, links back to your store.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;OAI-SearchBot&lt;/code&gt;, &lt;code&gt;Claude-SearchBot&lt;/code&gt;, &lt;code&gt;PerplexityBot&lt;/code&gt;, &lt;code&gt;Google-Extended&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅ Always allow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User-initiated&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fetches your page when a user asks AI to visit a specific URL. May cite your product page directly.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChatGPT-User&lt;/code&gt;, &lt;code&gt;Claude-User&lt;/code&gt;, &lt;code&gt;Perplexity-User&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅ Always allow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Training crawlers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Collects content for model training. No attribution, no traffic back.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GPTBot&lt;/code&gt;, &lt;code&gt;ClaudeBot&lt;/code&gt;, &lt;code&gt;Applebot-Extended&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;⚠️ Your choice&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The most common mistake:&lt;/strong&gt; blocking &lt;code&gt;GPTBot&lt;/code&gt; (training) thinking it removes you from ChatGPT search results. It does not. &lt;code&gt;GPTBot&lt;/code&gt; and &lt;code&gt;OAI-SearchBot&lt;/code&gt; are entirely separate bots. Blocking training crawlers has zero effect on AI search visibility — but blocking search crawlers makes you invisible immediately.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Every AI Bot That Matters in 2026
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bot&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Impact if blocked&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OAI-SearchBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ChatGPT&lt;/td&gt;
&lt;td&gt;Search index&lt;/td&gt;
&lt;td&gt;Invisible in all ChatGPT search answers. &lt;strong&gt;Most critical.&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GPTBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ChatGPT&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;Excluded from future GPT training. No effect on current search.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ChatGPT-User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ChatGPT&lt;/td&gt;
&lt;td&gt;User-initiated&lt;/td&gt;
&lt;td&gt;ChatGPT can't fetch your pages for users.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Claude-SearchBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;td&gt;Search index&lt;/td&gt;
&lt;td&gt;Invisible in Claude's real-time web search answers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClaudeBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;Excluded from future Claude training data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Claude-User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;td&gt;User-initiated&lt;/td&gt;
&lt;td&gt;Claude can't fetch your pages for users.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PerplexityBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Perplexity&lt;/td&gt;
&lt;td&gt;Search index&lt;/td&gt;
&lt;td&gt;Invisible in Perplexity answers and recommendations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Perplexity-User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Perplexity&lt;/td&gt;
&lt;td&gt;User-initiated&lt;/td&gt;
&lt;td&gt;Perplexity can't fetch your pages for users.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Google-Extended&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gemini&lt;/td&gt;
&lt;td&gt;Search + training&lt;/td&gt;
&lt;td&gt;Not cited in Gemini AI Overviews or Google Shopping AI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Applebot-Extended&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apple Intelligence&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;Excluded from Apple Intelligence training data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;anthropic-ai&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;Deprecated&lt;/td&gt;
&lt;td&gt;Legacy name for ClaudeBot. Keep rules for backwards compatibility.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anthropic expanded to three bots in early 2026.&lt;/strong&gt; Sites that only reference &lt;code&gt;ClaudeBot&lt;/code&gt; are now missing &lt;code&gt;Claude-SearchBot&lt;/code&gt; (live search) and &lt;code&gt;Claude-User&lt;/code&gt; (user-initiated fetching). If your robots.txt hasn't been updated since 2024, this almost certainly applies to your store.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Default Magento robots.txt Problem
&lt;/h2&gt;

&lt;p&gt;Magento's default &lt;code&gt;robots.txt&lt;/code&gt; starts with a wildcard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: *
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;index&lt;/span&gt;.&lt;span class="n"&gt;php&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /*?
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;checkout&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;app&lt;/span&gt;/
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wildcard establishes a baseline that every bot inherits. If your deployment script, hosting provider, or a staging migration has added &lt;code&gt;Disallow: /&lt;/code&gt; anywhere — AI bots are caught in it silently, with no error logged anywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check this right now.&lt;/strong&gt; Open &lt;code&gt;https://yourstore.com/robots.txt&lt;/code&gt; and look for &lt;code&gt;Disallow: /&lt;/code&gt; on its own line. If it exists without an explicit &lt;code&gt;Allow: /&lt;/code&gt; for each AI bot listed above it — every one of those bots is blocked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Quick check — if this returns output, you have a problem&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/robots.txt | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^Disallow: /$"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Where Magento Serves robots.txt — Two Scenarios
&lt;/h2&gt;

&lt;p&gt;Before editing, identify which method your store uses. Editing the wrong one has no effect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario A: Magento Admin (most common)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if Magento manages robots.txt&lt;/span&gt;
bin/magento config:show design/search_engine_robots/default_robots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it returns a value, edit via: &lt;strong&gt;Content → Design → Configuration → [Store view] → Edit → Search Engine Robots → Edit custom instruction of robots.txt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario B: Static file in pub/&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if a static file exists and is being served&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/www/html/pub/robots.txt
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://yourstore.com/robots.txt
&lt;span class="c"&gt;# If no X-Magento headers appear, the file is served statically&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;pub/robots.txt&lt;/code&gt; directly, or remove it to let Magento Admin take over.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Multi-store:&lt;/strong&gt; Each store view can have its own robots.txt. If you run multiple stores on different domains, configure each store view separately in Admin → Design → Configuration.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Complete robots.txt for Magento 2
&lt;/h2&gt;

&lt;p&gt;Paste this as your full configuration. AI bot entries must appear &lt;strong&gt;before&lt;/strong&gt; the wildcard &lt;code&gt;User-agent: *&lt;/code&gt; block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# ============================================================
# AI SEARCH &amp;amp; INDEXING BOTS — Always allow
# Blocking these makes your store invisible in AI search answers.
# ============================================================
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;OAI&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Claude&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;PerplexityBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Google&lt;/span&gt;-&lt;span class="n"&gt;Extended&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="c"&gt;# ============================================================
# USER-INITIATED FETCHERS — Always allow
# ============================================================
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;ChatGPT&lt;/span&gt;-&lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Claude&lt;/span&gt;-&lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Perplexity&lt;/span&gt;-&lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="c"&gt;# ============================================================
# TRAINING CRAWLERS — your choice
# Blocking does NOT affect search visibility.
# Change Allow to Disallow to opt out of training data collection.
# ============================================================
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;GPTBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;ClaudeBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;anthropic&lt;/span&gt;-&lt;span class="n"&gt;ai&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Applebot&lt;/span&gt;-&lt;span class="n"&gt;Extended&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="c"&gt;# ============================================================
# TRADITIONAL SEARCH ENGINES
# ============================================================
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Googlebot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Bingbot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="c"&gt;# ============================================================
# ALL OTHER BOTS — standard Magento rules
# AI bots above are explicitly allowed before this wildcard.
# ============================================================
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: *
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="c"&gt;# Magento paths — block from all crawlers
&lt;/span&gt;&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;admin&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;adminhtml&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;api&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;rest&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;graphql&lt;/span&gt;
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;cron&lt;/span&gt;.&lt;span class="n"&gt;php&lt;/span&gt;
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;var&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;lib&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;dev&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;index&lt;/span&gt;.&lt;span class="n"&gt;php&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /*?&lt;span class="n"&gt;SID&lt;/span&gt;=
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /*?&lt;span class="err"&gt;___&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;=
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;checkout&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;customer&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;wishlist&lt;/span&gt;/
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;review&lt;/span&gt;/

&lt;span class="c"&gt;# ============================================================
# SITEMAPS
# ============================================================
&lt;/span&gt;&lt;span class="n"&gt;Sitemap&lt;/span&gt;: &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;yourstore&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;/&lt;span class="n"&gt;sitemap&lt;/span&gt;.&lt;span class="n"&gt;xml&lt;/span&gt;
&lt;span class="n"&gt;Sitemap&lt;/span&gt;: &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;yourstore&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;/&lt;span class="n"&gt;llms&lt;/span&gt;.&lt;span class="n"&gt;txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Order is not optional.&lt;/strong&gt; robots.txt uses first-match semantics per crawler. If &lt;code&gt;User-agent: *&lt;/code&gt; with &lt;code&gt;Disallow: /&lt;/code&gt; appears before the AI bot entries, those AI bots are permanently blocked — the rules below are never reached.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Four Mistakes That Block AI Bots
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ Mistake 1 — Disallow: / left on from staging
&lt;/h3&gt;

&lt;p&gt;Many Magento stores use &lt;code&gt;Disallow: /&lt;/code&gt; on staging. This is frequently copied to production and never removed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common sources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Magento Admin: Stores → Configuration → General → Design → Search Engine Robots&lt;/li&gt;
&lt;li&gt;Manually edited &lt;code&gt;pub/robots.txt&lt;/code&gt; copied from staging&lt;/li&gt;
&lt;li&gt;CI/CD pipelines that sync the full staging filesystem to production&lt;/li&gt;
&lt;li&gt;Managed hosts (Hypernode, Nexcess, Cloudways) applying restrictive defaults on new environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Mistake 2 — Wildcard block placed before AI bot rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# ❌ WRONG — wildcard fires first, AI bot rules below it are ignored
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: *
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;OAI&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /  &lt;span class="c"&gt;# ← never reached, bot already matched the wildcard above
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# ✅ CORRECT — explicit AI rules appear before the wildcard
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;OAI&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: *
&lt;span class="n"&gt;Disallow&lt;/span&gt;: /&lt;span class="n"&gt;checkout&lt;/span&gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ❌ Mistake 3 — Using outdated Anthropic bot names
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Deprecated — no longer reflect Anthropic's bot infrastructure
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Claude&lt;/span&gt;-&lt;span class="n"&gt;Web&lt;/span&gt;     &lt;span class="c"&gt;# retired 2024
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Anthropic&lt;/span&gt;-&lt;span class="n"&gt;AI&lt;/span&gt;   &lt;span class="c"&gt;# retired 2024
&lt;/span&gt;
&lt;span class="c"&gt;# Current names (2026)
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;ClaudeBot&lt;/span&gt;        &lt;span class="c"&gt;# training
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Claude&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt; &lt;span class="c"&gt;# live search index ← missing from most configs
&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt;: &lt;span class="n"&gt;Claude&lt;/span&gt;-&lt;span class="n"&gt;User&lt;/span&gt;      &lt;span class="c"&gt;# user-initiated fetching ← missing from most configs
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ❌ Mistake 4 — robots.txt served from cache or static file
&lt;/h3&gt;

&lt;p&gt;Some hosting setups bypass Magento when serving &lt;code&gt;robots.txt&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nginx static rule&lt;/strong&gt; serves &lt;code&gt;pub/robots.txt&lt;/code&gt; before Magento handles the request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN caching&lt;/strong&gt; — Cloudflare or Fastly caches the old file with long TTLs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Varnish&lt;/strong&gt; returns cached response without hitting the application
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Diagnosis — if no X-Magento headers, file is served statically&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://yourstore.com/robots.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix for Nginx&lt;/strong&gt; — ensure this location block is present:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;/robots.txt&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.php&lt;/span&gt;&lt;span class="nv"&gt;$is_args$args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix for Cloudflare&lt;/strong&gt; — purge cache for &lt;code&gt;/robots.txt&lt;/code&gt; via dashboard, or add a Cache Rule to bypass caching for that path.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verify the Fix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check all critical AI search bots have Allow: /&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/robots.txt | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A1&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"OAI-SearchBot|Claude-SearchBot|PerplexityBot|Google-Extended"&lt;/span&gt;

&lt;span class="c"&gt;# Check server logs to confirm bots are actually crawling&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Ei&lt;/span&gt; &lt;span class="s2"&gt;"OAI-SearchBot|Claude-SearchBot|PerplexityBot"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/nginx/access.log | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Via AEO audit module — checks all bots + validates rule order&lt;/span&gt;
composer require angeo/module-aeo-audit
bin/magento setup:upgrade
bin/magento angeo:aeo:audit

&lt;span class="c"&gt;# ✓ PASS  robots.txt — AI Bot Access&lt;/span&gt;
&lt;span class="c"&gt;#         OAI-SearchBot ✓  Claude-SearchBot ✓  ChatGPT-User ✓&lt;/span&gt;
&lt;span class="c"&gt;#         ClaudeBot ✓  Claude-User ✓&lt;/span&gt;
&lt;span class="c"&gt;#         PerplexityBot ✓  Google-Extended ✓&lt;/span&gt;

&lt;span class="c"&gt;# Multi-store — run per store view&lt;/span&gt;
bin/magento angeo:aeo:audit &lt;span class="nt"&gt;--store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;de
bin/magento angeo:aeo:audit &lt;span class="nt"&gt;--store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  After robots.txt — What's Next
&lt;/h2&gt;

&lt;p&gt;Fixing robots.txt is the access layer. Once AI bots can reach your store, the signals that determine whether you actually appear in AI answers are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;llms.txt&lt;/strong&gt; — machine-readable index of your catalog that AI assistants parse in seconds → &lt;a href="https://packagist.org/packages/angeo/module-llms-txt" rel="noopener noreferrer"&gt;angeo/module-llms-txt&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product JSON-LD schema&lt;/strong&gt; — structured markup that tells AI exactly what your products cost and where to buy them → checked by &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;angeo/module-aeo-audit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI product feed&lt;/strong&gt; — structured feed required for ChatGPT Shopping eligibility → &lt;a href="https://packagist.org/packages/angeo/module-openai-product-feed" rel="noopener noreferrer"&gt;angeo/module-openai-product-feed&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# See all 8 AEO signals and your complete score&lt;/span&gt;
bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q: Does blocking GPTBot affect ChatGPT recommendations?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No — but blocking &lt;code&gt;OAI-SearchBot&lt;/code&gt; does. These are separate bots. &lt;code&gt;GPTBot&lt;/code&gt; collects training data; &lt;code&gt;OAI-SearchBot&lt;/code&gt; builds the index ChatGPT uses for search answers. Blocking &lt;code&gt;GPTBot&lt;/code&gt; has no effect on whether your store appears in ChatGPT results. Blocking &lt;code&gt;OAI-SearchBot&lt;/code&gt; removes you from ChatGPT search answers entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What is OAI-SearchBot and why does it matter more than GPTBot?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OAI-SearchBot&lt;/code&gt; is OpenAI's crawler that powers ChatGPT real-time search results and product recommendations. It determines whether your store appears in ChatGPT answers today. &lt;code&gt;GPTBot&lt;/code&gt; collects training data for future model versions — its effects are long-term and indirect. Both should be allowed, but &lt;code&gt;OAI-SearchBot&lt;/code&gt; is the one that determines your current search visibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How do I check which AI bots are blocked in Magento 2?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://yourstore.com/robots.txt | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'searchbot\|gptbot\|claude\|perplexity\|google-extended'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If nothing appears, bots may be blocked by a wildcard &lt;code&gt;Disallow: /&lt;/code&gt; rule. The fastest automated check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require angeo/module-aeo-audit
bin/magento setup:upgrade
bin/magento angeo:aeo:audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It checks all bots, validates rule order, and reports exact status for each one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Should I allow training bots like GPTBot and ClaudeBot?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For most ecommerce stores, yes. Allowing training crawlers means your product descriptions and category content contribute to how AI models understand and describe products in your category — which indirectly improves recommendation quality over time. If you have legal or privacy reasons to opt out, block only the training bots (&lt;code&gt;GPTBot&lt;/code&gt;, &lt;code&gt;ClaudeBot&lt;/code&gt;, &lt;code&gt;Applebot-Extended&lt;/code&gt;) — your search visibility is not affected.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Check all AI bots and 7 other AEO signals in one command — free, MIT licensed:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📦 &lt;a href="https://packagist.org/packages/angeo/module-aeo-audit" rel="noopener noreferrer"&gt;Install AEO Audit Module&lt;/a&gt;&lt;br&gt;
🌐 &lt;a href="https://angeo.dev/ai-magento-audit/" rel="noopener noreferrer"&gt;Free Web Self-Assessment&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://angeo.dev/magento-2-robots-txt-chatgpt-gemini-ai-bots/" rel="noopener noreferrer"&gt;angeo.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>magento</category>
      <category>aeo</category>
      <category>chatgpt</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
