Simple steps to make your online store AI-ready
Ordered by what we've actually seen break on real e-commerce sites — not by what looks important on paper. Five specific fixes your engineering team can ship without re-architecting anything: real button elements, accessible variant selectors, schema.org Product data, agent-friendly robots.txt, and bot-protection that doesn't 403 well-behaved agents.
TL;DR. Five fixes, ordered by what actually breaks: (1) real <button> for add-to-cart instead of <div onClick>; (2) <button> elements with aria-label for variant selectors (color swatches especially); (3) schema.org Product JSON-LD with name, offers.price, offers.priceCurrency, offers.availability; (4) robots.txt that allows GPTBot, ClaudeBot, PerplexityBot; (5) bot protection that doesn't 403 headless browsers with honest user-agents. llms.txt is fine GEO hygiene for the upstream visibility layer (Anthropic + Perplexity consult it there), but it's not the lever for task-completion — that's the DOM. Run our scanner before and after each fix and watch the score move.
In this article:
- 0. The pre-step: measure before you fix
- 1. Your add-to-cart button must be a real button
- 2. Your variant selectors must have accessible names
- 3. Add schema.org Product structured data
- 4. Your robots.txt must allow agents
- 5. Your bot protection must not 403 well-behaved agents
- What we deliberately left off
- Frequently asked questions
Most "make your site AI-ready" lists look like a generic SEO checklist with the word "AI" pasted on top. Add schema.org. Write good alt text. Make sure your sitemap is fresh. All true. All necessary. None of it is what actually breaks first.
We've watched real agents (Claude Desktop via browser MCP, ChatGPT Operator, browser-use, Perplexity) attempt purchase tasks on real e-commerce sites. The same five things break repeatedly, in roughly the same order. This list is ordered by what we see fail, not by what the spec says is important.
This is for the Front End / Engineering Lead who owns the DOM and the checkout, and the Product Director who's going to forward this to them. Each step is one specific change. None of them require re-architecting. Most of them can be shipped in a single sprint by someone who already knows the codebase.
0. The pre-step: measure before you fix
This isn't a step exactly, but it should come before the others.
Run your domain through the Serge scanner. It'll tell you which of the steps below you actually need. The scanner produces a 0–100 score for agent product-findability and lists every failing structural check with a one-line fix. Free, no signup, 30 seconds.
Working from a baseline beats working from a list. Skip to the steps that matter for your site.
1. Your add-to-cart button must be a real button
This is the single most common failure we see, and it's at the top of the list because nothing else matters if this is broken.
Open your top-three product detail pages. Inspect the "Add to cart" CTA. If it's not a real <button> element — or doesn't have role="button" plus an accessible name plus a keyboard handler — fix it first.
What we see: <div className="add-to-cart" onClick={...}>Add to cart</div> — visually a button, semantically text. An agent reading the accessibility tree sees text: "Add to cart", doesn't know it's interactive, doesn't click it.
The fix:
<!-- before -->
<div className="add-to-cart" onClick={handleAddToCart}>Add to cart</div>
<!-- after -->
<button
type="button"
className="add-to-cart"
onClick={handleAddToCart}
>
Add to cart
</button>
That's the entire change. The styling stays exactly the same (CSS doesn't care whether it's a <div> or a <button>). The accessibility tree now reads button: "Add to cart". Agents and screen-reader users both win.
Time to ship: under an hour for a competent FE engineer. Test plan: tab through the page, confirm focus reaches the button, confirm Enter and Space activate it.
2. Your variant selectors (size, color, capacity) must have accessible names
Second most common. A variant selector is the second place an agent gets stuck, because if it picks the wrong variant or can't pick one at all, it can't "Add to cart" the right thing.
What we see: A grid of color swatches rendered as <div> elements with background colors, no text. To a human: obviously color choices. To an agent: a row of unlabeled buttons.
<!-- before — unreadable to agents -->
<div className="color-swatches">
<div className="swatch" style={{background: '#4a1a1a'}} onClick={() => selectColor('burgundy')} />
<div className="swatch" style={{background: '#1a2444'}} onClick={() => selectColor('navy')} />
<div className="swatch" style={{background: '#888'}} onClick={() => selectColor('silver')} />
</div>
The fix: Use <button> elements with accessible names. Keep the visual identical.
<!-- after -->
<div role="radiogroup" aria-label="Color">
<button
type="button"
role="radio"
aria-checked={selected === 'burgundy'}
aria-label="Burgundy"
onClick={() => selectColor('burgundy')}
style={{background: '#4a1a1a'}}
/>
<button
type="button"
role="radio"
aria-checked={selected === 'navy'}
aria-label="Navy"
onClick={() => selectColor('navy')}
style={{background: '#1a2444'}}
/>
<button
type="button"
role="radio"
aria-checked={selected === 'silver'}
aria-label="Silver"
onClick={() => selectColor('silver')}
style={{background: '#888'}}
/>
</div>
Two changes: real <button> elements with aria-label (so the agent reads "Burgundy" / "Navy" / "Silver"), and a radiogroup wrapper so the agent understands these are mutually-exclusive choices for one variant axis.
For size selectors, the same pattern applies — but you can usually go further and use a real <select> if your design system allows it. A native <select> is the cheapest possible agent-friendly variant picker.
Time to ship: half a day across the product templates. Test plan: keyboard-navigate the swatches with arrow keys, confirm only one can be selected at a time.
3. Add schema.org Product structured data
This is third because it's the highest-leverage signal that is widely read by agents. Without it, an agent looking at your product page has to infer the price, the availability, and the product name from the DOM. With it, the agent reads structured fields directly.
The fix: A <script type="application/ld+json"> block in the <head> (or before </body>) of every product page, populated from your data model:
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Laptop X-15",
"image": "https://yourstore.ch/img/laptop-x-15-hero.jpg",
"description": "15-inch laptop with 16GB RAM, 512GB SSD.",
"sku": "LX15-S",
"brand": {
"@type": "Brand",
"name": "Yourstore"
},
"offers": {
"@type": "Offer",
"url": "https://yourstore.ch/p/laptop-x-15",
"priceCurrency": "CHF",
"price": "299.00",
"availability": "https://schema.org/InStock"
}
}
</script>
Critical fields: name, offers.price, offers.priceCurrency, offers.availability. Without these, an agent comparing two stores doesn't have a clean read on whether you're in stock or what you charge.
If you're on Shopify, this is partially populated by default — but check what's actually emitted. Many themes omit availability or use a malformed format. If you're on a custom stack, your product page server-side rendering needs to emit this from the same data source your <h1> and price element use, so they can't drift.
Time to ship: one to two days, mostly because you'll be picking the right schema.org subtypes for your category (apparel uses Product with size, books use Book, etc.).
4. Your robots.txt must allow agents (or at least not block them)
Often overlooked. The agent's first request to your site is usually GET /robots.txt. If you've copy-pasted a robots.txt from an SEO blog post that "blocks all bots except Googlebot," you have just told ChatGPT and Claude to leave.
What to check: open https://yourstore.ch/robots.txt. Look for blanket disallow rules.
The fix: explicit allows for known agent user-agents, or at least no blanket Disallow: / for everything-except-Google.
# robots.txt
User-agent: GPTBot
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: OAI-SearchBot
Allow: /
User-agent: *
Allow: /
Disallow: /admin
Disallow: /api
Sitemap: https://yourstore.ch/sitemap.xml
A note on the broader debate: there's a real conversation to be had about whether you want agents on your site at all. AI Overviews crawling your content without sending traffic is a legitimate concern. But that conversation is about content sites, not commerce — for an e-commerce store, agent traffic with intent to buy is incoming customers, not content scraping. We'd suggest separating those two debates and not letting your content-team's robots.txt policy block your commerce-team's customers.
Time to ship: 5 minutes. Test plan: curl https://yourstore.ch/robots.txt and read it back.
5. Your bot protection must not 403 well-behaved agents
The frustrating cousin of #4. Even if your robots.txt says yes, your Cloudflare / HUMAN / Kasada / Imperva configuration may return a 403 or a CAPTCHA to a headless Chromium browser — which is exactly what every browser-based AI agent runs on.
What to check: From a terminal, run:
curl -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 HeadlessChrome/124.0.0.0 Safari/537.36" \
-I https://yourstore.ch/
If you get a 403 or 503 (not a 200), your bot protection is blocking headless browsers. That's most agents.
The fix: This one isn't a one-line code change. It's a security-team conversation. The shape of the right policy:
- Block: unauthenticated POST requests, password-stuffing patterns, abusive scrape rates, known malicious user-agents
- Allow: headless Chromium with an honest user-agent doing normal product-page navigation at a reasonable rate
Most enterprise bot-protection products support "challenge bots that look like agents but don't 403 them outright." Your security lead will know the lever — surface that this is now a commercial decision, not just a security one. The cost of a false-positive 403 against a Claude Desktop customer is a lost sale.
Time to ship: one conversation + a config change. Test plan: re-run the curl after the change.
What we deliberately left off
To keep this honest, here are the items most "AI readiness" lists include that we don't think belong in the top five:
- llms.txt — fine GEO hygiene, NOT a task-completion fix. Anthropic and Perplexity have publicly confirmed they consult
/llms.txtat their upstream retrieval/indexing layer (deciding which URL to send an agent to). But once an agent is on your product page making click decisions, it does not refetchllms.txt— it reads the DOM. So publishing one helps the upstream visibility play; recommending it as your first task-completion fix is selling the wrong layer. We unpack the full layer distinction in the companion post. The five steps above will move your scanner score by 30–40 points;llms.txtwon't move it materially because the scanner measures the task-completion layer, not the upstream indexing layer. - AI chat widget on your site — different problem. A chat widget helps human users; it doesn't help an agent that's already browsing your product pages.
- "AI-friendly meta descriptions" — meta descriptions are useful for search results, not for agent task completion. Don't reorder priorities for this.
- Token / context-length optimization — relevant if you're building an agent. Not relevant if you're being browsed by one. Agents don't pay per token to look at your site; you don't owe them token efficiency.
- Rewriting your copy "for AI" — your product page copy should describe your products clearly to a human. Agents read the same copy and benefit from the same clarity. There's nothing special to do.
The reason these don't make the top five isn't that they're wrong — it's that they don't move the needle on the failure mode we actually see. We're optimizing for agent completes the buy task, which is a structural problem, not a content problem.
What this looks like at the end
A store that's done #1–#5 will:
- Allow agents to reach it (steps 4, 5)
- Let agents find products (step 3 + clean catalog navigation, which usually exists already)
- Let agents read the product page (step 3)
- Let agents pick the right variant (step 2)
- Let agents add to cart (step 1)
At which point your task-completion rate on the Serge scanner goes from ~30 (typical median) to ~70+ (the cluster where agents actually succeed). Each individual step is small. The cumulative effect is the difference between agents going to your store or going to a competitor's.
How to know when you're done
Run the scanner before, run the scanner after. The score should move. Specific findings should turn from fail to pass. If a finding doesn't move after you ship a fix, you didn't actually ship the fix you thought you did — happens more often than you'd expect with frontend rebuilds.
We re-scan and surface the delta automatically once you're on a paid tier with the snippet installed; for one-off pre/post measurement, the public scanner is enough.
Run a scan. Get a baseline. Ship a fix. Re-scan. Watch the number move.
Frequently asked questions
How do I make my e-commerce store AI-ready?
Five specific fixes, ordered by what we see fail most often: (1) Use real <button> elements for add-to-cart instead of <div onClick> handlers — agents can't click roleless divs reliably. (2) Give variant selectors accessible names — wrap color swatches in a <div role="radiogroup"> with aria-label per swatch. (3) Add schema.org Product structured data to every product page with name, offers.price, offers.priceCurrency, and offers.availability. (4) Allow shopping-agent user-agents in robots.txt (GPTBot, ClaudeBot, PerplexityBot). (5) Configure bot protection to challenge rather than 403 headless browsers with honest user-agents.
Should I publish an llms.txt file to make my site AI-ready?
It depends which layer you're optimizing. Anthropic and Perplexity have publicly confirmed they consult /llms.txt during their upstream retrieval/indexing — the layer that decides which URL to send an agent to. So publishing one helps the upstream visibility play (GEO). But once an agent is on your product page making click decisions, it does not refetch /llms.txt — it reads the DOM. So llms.txt is fine GEO hygiene; it's not your first task-completion fix. Focus on DOM-level fixes (real <button> elements, accessible variant selectors, schema.org Product) before llms.txt if your concern is whether the agent can actually buy from you once it arrives.
Does adding a div with role="button" make a button AI-friendly?
Partially, but not reliably. role="button" tells the accessibility tree the element is interactive, which is the first half of the fix. The second half is keyboard semantics — Enter and Space activation, focus management, and a proper click handler attached to the right element. Real <button> elements handle all of this for free. A <div role="button"> often misses one of these, which is why agents fail on custom-built components. Use a real <button> unless your design system makes it impossible.
Which schema.org fields matter most for AI shopping agents?
Four fields on schema.org Product matter most: name (the product title agents quote when summarizing), offers.price (the current price as a string with no currency symbol), offers.priceCurrency (the ISO currency code, e.g., CHF or EUR), and offers.availability (one of the schema.org enum values like https://schema.org/InStock). Without these four, agents comparing two stores cannot get a clean read on whether you're in stock or what you charge — they fall back to scraping the DOM, which is fragile.
Does blocking GPTBot in robots.txt protect my content from AI?
It blocks the training crawler, not the shopping agent. There are two distinct user-agents from each AI vendor: a training/indexing bot (GPTBot, ClaudeBot, PerplexityBot) and a real-time agent that runs in a headless browser when a user delegates a task. The real-time agent does not announce itself with a fixed user-agent — it typically reports as headless Chrome. Blocking the training bot in robots.txt has no effect on agent-mediated shopping traffic. If you want to control content training, that's a separate decision from agent task completion — don't conflate them.
About the author. Yann Borie is the founder of Serge (Superstellar LLC, Zug, Switzerland). He spends his time instrumenting AI shopping agents on real e-commerce sites and turning what they fail at into shippable findings. Connect on LinkedIn.
This is the practical companion to How AI shopping agents actually see your website (the mental model) and Will AI agents hurt my e-commerce sales? Here's what we found (the commercial framing). Run a free scan and see your baseline.
More from the blog
- How AI shopping agents actually see your websiteResearch · 22. Mai 2026
- Will AI agents hurt my e-commerce sales? Here's what we foundPOV · 22. Mai 2026
- Why GA4 is blind to Claude shoppersPOV · 29. April 2026
Run the scanner on your store
Free, deterministic, 30 seconds. See exactly which agent failures apply to your domain.
Scan your domain