AEO & GEO
How the storefront makes itself legible to AI answer engines and generative search, with built-in content negotiation, structured data, and discovery surfaces.
AEO & GEO
Answer Engine Optimization (AEO) and Generative Engine Optimization (GEO) are the practices of making a site legible to the AI surfaces that increasingly mediate commerce — ChatGPT, Claude, Perplexity, Google AI Overviews, and the long tail of agent-driven shopping. Where classical SEO optimizes for crawlers that build a search index, AEO/GEO optimizes for models that read a page once and synthesize an answer. The legibility bar is higher: noisy markup, hydration-only data, and content trapped behind interaction all degrade an LLM's ability to recover the underlying facts.
The template ships with several built-in surfaces that contribute to AEO/GEO. The largest of them is content negotiation — serving structured markdown to clients that ask for it — but the supporting cast (JSON-LD schema, sitemaps, OpenGraph metadata) is what makes a page consistently parseable across surfaces.
Surfaces in the template
| Surface | What it does | Key files |
|---|---|---|
| Content negotiation | Serves clean markdown to AI clients via Accept: text/markdown | next.config.ts, app/md/**, lib/markdown/** |
| Schema.org JSON-LD | Embeds structured Product, BreadcrumbList, and Organization data | components/product-detail/schema.tsx, components/schema/** |
| Sitemap | Enumerates products, collections, and pages for crawlers | app/sitemap.ts, lib/shopify/operations/sitemap.ts |
| Robots | Declares crawl policy, including allowances for known AI user agents | app/robots.ts |
| OpenGraph & Twitter metadata | Provides title, description, and image previews per route | lib/seo.ts, route-level generateMetadata |
The rest of this page goes deep on content negotiation. The other surfaces are documented inline in the linked files.
Content Negotiation
Product, collection, and search pages serve structured markdown when clients send Accept: text/markdown. Browsers continue to receive HTML; AI agents and crawlers get clean, parseable markdown from the same URL.
This is built in and requires no configuration. Every markdown route lives under a single top-level app/md/ directory so all content-negotiation handlers are co-located and easy to find.
How it works
Browsers that don't send Accept: text/markdown are unaffected — the rewrite only fires when the header matches.
Testing
The Vary: Accept header ensures CDNs cache markdown and HTML responses separately.
What's included in the markdown
- Product pages — handle, brand, category, pricing, options, variants, specs, images, tags, and SEO metadata
- Collection pages — collection metadata, description, applied filters, available filters, products, pagination, image, and SEO metadata
- Search pages — query metadata, active collection filter, applied filters, available filters, products, and pagination state
Key files
| File | Purpose |
|---|---|
next.config.ts | Rewrite rules matching Accept: text/markdown |
app/md/products/[handle]/route.ts | Product markdown route handler |
app/md/collections/[handle]/route.ts | Collection markdown route handler |
app/md/search/route.ts | Search markdown route handler |
lib/markdown/product.ts | productToMarkdown() converter |
lib/markdown/collection.ts | collectionToMarkdown() converter |
lib/markdown/search.ts | searchResultsToMarkdown() converter |
lib/markdown/catalog.ts | Shared product/filter/pagination formatting helpers |
lib/markdown/utils.ts | Formatting helpers (prices, tables, escaping) |
Multi-locale
If you have enabled Shopify Markets, the rewrite fires before locale routing — no additional configuration is needed. Pass a ?locale= query parameter to the markdown endpoint for locale-specific pricing and collection/search context.