Originally published on angeo.dev
You installed robots.txt rules for GPTBot. You generated llms.txt. You added Product schema. The AEO audit is green. ChatGPT still recommends your competitor.
The problem is not what you added. It is how Magento renders product content — and whether AI extraction systems can actually reach it.
AI recommendation systems don't browse your store like a customer. They fetch raw HTML, parse it through an extraction layer, chunk the content into retrievable units, score those chunks against query intent, and synthesise an answer.
The extraction layer is where most Magento stores lose the race.
Content visibility for AI falls into four practical levels:
| Level | State | Extraction reliability |
| 1 | Server-rendered, early in HTML | High |
| 2 | Server-rendered but hidden/collapsed | Reduced |
| 3 | In DOM only after JS execution | Low |
| 4 | Loaded async after user interaction | Very low |
Googlebot handles levels 2–4 fine — it runs a full headless Chrome pipeline. Most AI crawlers do not. For AI, server-rendered HTML early in the document is what gets extracted reliably. Everything else is a gamble.
What Magento actually serves
Default Magento 2 wraps product descriptions inside a RequireJS tabs widget:
data-mage-init='{"tabs": {...}}'
In most Luma installations, the description is in the server-rendered HTML — but:
- marked as inactive (collapsed tab)
- positioned deep in the document after navigation, widget JSON, form keys, boilerplate
- structurally ambiguous to an extraction parser
Run this to see your actual first impression on AI crawlers:
curl -s "https://yourstore.com/your-product-url.html" \
| python3 -c "
import sys, re
html = sys.stdin.read()
text = re.sub(r'<[^>]+>', ' ', html)
text = re.sub(r'\s+', ' ', text).strip()
print(text[:3000])
"
If your product description text is not clearly readable in those first 3000 characters — you are at Level 2 at best, and competing at a structural disadvantage against every store that renders their description at Level 1.
Fix 1 — Activate the tab by default (quick win)
<!-- catalog_product_view.xml in your theme -->
<referenceBlock name="product.info.details">
<arguments>
<argument name="config" xsi:type="array">
<item name="settings" xsi:type="array">
<item name="active" xsi:type="boolean">true</item>
</item>
</argument>
</arguments>
</referenceBlock>
Keeps the tab UI for visitors. Removes the CSS-hidden state so the description is exposed at page load. Level 2 collapsed → Level 2 visible. Takes 5 minutes, no module required.
Fix 2 — Render description above tabs (structural fix)
<!-- catalog_product_view.xml -->
<referenceContainer name="product.info.main">
<block class="Magento\Catalog\Block\Product\View\Description"
name="product.description.above.tabs"
template="YourVendor_Theme::product/description-visible.phtml"
after="product.info.price">
</referenceContainer>
<?php
// description-visible.phtml
$description = $block->getProduct()->getData('description');
if (!$description) return;
?>
<section class="product-description-aeo" itemprop="description">
<?= /* @noEscape */ $description ?>
</section>
Description is now at Level 1 — unconditional, server-rendered, early in the document. Keep the tabs further down for UX. Both coexist without conflict.
Fix 3 — Render all tab content server-side (comprehensive)
Override details.phtml so all tab content is in the initial HTML response. The tabs widget handles visibility via CSS only — active tab is visible, others are hidden. AI parsers reading raw HTML see everything.
Hyva Theme note
Hyva uses Alpine.js x-show instead of RequireJS tabs. Description is usually in the HTML source — but Alpine bindings add structural noise. Most reliable fix: render description once outside the Alpine component, as a clean server-rendered block, early in the layout. Same pattern as Fix 2 above, same result.
Check your JSON-LD delivery
Same principle applies to schema. If JSON-LD is injected via GTM or hydrated client-side, AI parsers often miss it entirely.
curl -s "https://yourstore.com/your-product.html" \
| grep -o '"@type": "Product"'
No output = client-side schema = invisible to most AI extraction pipelines.
Server-rendered JSON-LD in <head> is the only reliable delivery method for AI systems.
Bottom line
AEO guides focus on what to add. This problem is about how content is exposed — position in the document, server vs client rendering, structural clarity for extraction parsers.
Most Magento stores have the right content. It just never reaches the layer that determines whether their products become AI recommendation candidates.
The fix takes under an hour. No new modules, no API keys — layout XML overrides in your theme.
Run the curl test on your top-selling product now.
Full article (all three fix approaches with complete code, Hyva deep-dive, schema delivery comparison): angeo.dev →
Free AEO audit tool (CLI, MIT licensed): angeo/module-aeo-audit