Agorastore marketplace · Platform benchmark · 21 July 2026

The marketplace, rebuilt.
Then measured.

The old marketplace showed a near-empty shell to people and AI, and a second, hidden app to Google. The new platform serves one real page to everyone — and it wins every single comparison: speed, accessibility, SEO, AI readiness, social sharing, and the architecture underneath.

V1 — current production stack V2 — build 849 · market-front-web:v356 3 pages × 2 form factors × 3 runs · Lighthouse 13.4.1
+0 / +0
Lighthouse performance points, desktop / mobile
0×3
accessibility, SEO & best practices — every page
5.4×
faster page-to-page navigation
0/100
AI & GEO readiness — V1 scores 25
0%
faster largest-content render on desktop home
01 · The verdict

Every category. Both form factors. No exception.

Same Lighthouse version, same pages, same three-run protocol, same third-party exclusions applied to both platforms. V2 wins all six page / form-factor match-ups — and turns three categories into perfect scores.

Performance values are the mean of the three per-page Lighthouse aggregates. The controlled protocol excludes the shared consent/chat/analytics stack from both versions — the same third parties, removed from both sides. SEO for V1 spans 66–69 across pages.

02 · The platform

One application, every audience.

V1 is really two applications behind one URL: browsers and AI agents get an empty SPA shell, while a separate server-rendering stack serves Google alone. V2 is one Nuxt application that answers everyone with real content — and dresses itself per brand from the request host. Pick an audience:

V1 · OLD

Browser

V2 · NEW

Browser

A
agorastore.fr
theme, copy, OG cards & sitemaps resolved from the host
A
auctelia.com
same build, zero code branches — pure configuration
03 · Cold-load speed

The old app painted a loader fast.
The new one paints the marketplace.

V1's early first paint is a spinner — the content arrives much later, client-side. The number that matters is LCP: when the main content is actually on screen. Watch the same three pages render on both platforms, at real relative speed:

−57%
transfer weight on desktop home — 2.82 → 1.21 MB
0 ms
total blocking time on every desktop page
0.000
layout shift on every V2 page — V1 up to 0.021
88
mobile Lighthouse on home & catalogue — V1: 62 / 61
Full Lighthouse metrics — all pages, both form factors

Mobile product remains the honest weak spot: 7.71 s LCP (score 70) — still 49% faster than V1's 15.25 s, and the main gallery image is a known, targeted fix.

05 · Search discovery

From a sitemap microservice with an S3 bucket…
to a URL the app just answers.

On V1, being discoverable required an entire separate system: a dedicated Node service in its own repo, triggered over HTTP, writing XML files to S3 per shop, wired back through HAProxy. Today, on production V1, robots.txt answers 403 and the sitemap URLs return HTML. On V2, discovery is a native part of the application — identical in every environment.

⛓️ V1 — the sitemap supply chain

A separate repository (auctelia/sitemaps), its own Docker deploy, its own failure modes.
🕹️
Manual / scheduled HTTP triggers
per type, per year, per shop
🧱
Sitemaps microservice
own repo · own deploy · own monitoring
🪣
S3 buckets, one folder per shop
XML files uploaded, drift risk vs prod URLs
🔀
HAProxy routes /sitemap* to the bucket
edge config as a dependency
Where it stands today: production robots.txt returns 403 and sitemap URLs serve the SPA HTML shell — Google currently discovers products through the hidden crawler app and internal links only.

⚡ V2 — discovery is just the app

No extra repo, no bucket, no proxy rule. The same deployed application generates and serves everything, with the same result in every environment.
🛍️
market-front
one Nuxt app · per-tenant from the request host
🗺️
sitemap_index.xml — 349 sitemaps
1 pages map + 348 monthly product maps
🎯
Legacy visibility rules, preserved
age · category strategy · bids · price · followers
robots.txt → 200 sitemap_index.xml → 200 July map: 383 URLs · 103 KB · 1.05 s cold chunked under the 10k search limit
At full scale: the source projection validates ≈84,158 localized product URLs for Agorastore and ≈52,243 for Auctelia — served monthly-chunked so no process ever holds the whole corpus in memory.
Discovery surfaces, side by side
Every row measured live — V1 on current production, V2 on build 849.
SurfaceV1 · oldV2 · new
robots.txt403S3 AccessDenied XML instead of a crawler policy200valid policy — search allowed, AI-training bots opted out
Sitemap indexHTMLsitemap URLs return the SPA shell, not XML200valid XML — 1 pages map + 348 monthly product maps
Product URLs0no first-party discovery surface at all383in the July map alone · ≈84,158 + 52,243 localized URLs at full scale
Canonicals & hreflangpartialonly inside the hidden crawler rendererevery pagerequest-aware canonical + 5-locale alternates in universal SSR
Lighthouse SEO66–69measured on the browser SPA100on all six page / form-factor runs
06 · AI & GEO readiness

When ChatGPT visits V1, it finds nothing.
V2 speaks its language natively.

Answer engines are becoming a real acquisition channel — and they don't execute JavaScript apps to guess a price. On V1, GPTBot and PerplexityBot receive the same empty shell as browsers, and every AI surface returns 404. V2 gives an agent full visibility of the platform: native Markdown for every route, a guided llms.txt map, structured data on every page, and complete product indexing through the sitemaps. The rubric below scores five criteria by weight — then each one is broken down.

0V1 · oldAI / GEO readiness
0V2 · newevidence-based, /100
Universal rendering
825/25

The single biggest criterion: can any agent read the page at all? V1 only renders content for Google's hidden crawler app — browsers, GPTBot and Perplexity get an empty shell. V2 serves one complete SSR document to every user agent, so the page an AI parses is exactly the page a human sees. No cloaking, no parity risk.

Structured semantics
1220/20

V1's JSON-LD exists only inside the Google-only renderer. V2 emits a full Schema.org graph in universal SSR: WebSite, WebPage, Organization and ImageObject sitewide; Product, Offer and BreadcrumbList with resolved labels on every product — generated from the same data source as the visible page, so it can never drift.

AI-native text surfaces
023/25

V1 has literally nothing: llms.txt, llms-full.txt and every .md mirror return 404. V2 detects AI agents and serves native Markdown for every route, publishes a machine-readable site map in llms.txt and a 181.6 KB full-content index. The two points deliberately left: volatile auction data stays in per-product .md rather than one giant stale index.

Robots, canonicals & discovery
220/20

V1 production blocks itself: robots.txt answers 403 and sitemaps return HTML. V2 pairs a valid crawler policy with 349 sitemaps covering the entire product corpus, request-aware canonicals and five-locale hreflang on every route — the whole discovery chain works end to end.

Extractable clarity
38/10

To learn a V1 product's price, a model must execute an SPA or dig through ~800 KB of crawler markup. A V2 product is 3–4 KB of Markdown: title, price, characteristics, dates, seller, canonical link. Two points remain: some pages still carry navigation context an agent must skip.

Where the wins come from
Two Nuxt SEO modules plus one platform layer — configured once, applied to every route, identical in every environment.
@nuxtjs/seomodule
  • Canonicals + hreflang — request-aware, five locales, every route
  • Schema.org graph — site & product structured data during SSR
  • Robots + sitemap engines — policy and XML served natively
  • OG images — 1200×630 cards rendered from Vue templates, in tenant colors
nuxt-ai-readymodule
  • Agent detection — GPTBot & PerplexityBot routed to native Markdown mirrors of every route
  • llms.txt + llms-full.txt — a guided map plus a 181.6 KB content index
  • Content-Signal policy — search ✓, AI answers ✓, model training ✗
  • IndexNow — pushes fresh URLs to search engines
Platform layercustom
  • Tenant resolution — theme, copy and domain resolved from the request host for both brands
  • One product source of truth — a single composable feeds meta, JSON-LD, the OG card and the Markdown export
  • Chunked product sitemaps — the legacy visibility score re-implemented on public search data, 348 monthly maps
An agent's full path: llms.txt sitemap_index.xml product page .md + JSON-LD citation with canonical link
V2 — all 200 V1 — all 404

Everything shown is the live deployed response, captured as-is. llms-full.txt serves 181.6 KB of indexed page content; volatile product data is deliberately left to per-product Markdown + the XML sitemaps, which is the safer design for auction inventory.

07 · Markdown on demand

Same product, two answers.
One is 67× lighter.

A browser needs the whole page — markup, styles, hydration state. An agent only needs the facts. V2 serves both from the same URL: ask as a browser, get the full document; ask as GPTBot (or append .md), get pure Markdown. Below, the two real responses for the same product. Race them — find the price:

GET /…/agora-405863text/html · 255.5 KB · ≈64,000 tokens
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Christmas light decorations – Set of 34 - Sale as is | Agorastore</title><link rel="canonical" href="https://…/used-equipment/christmas-light-decorations-set-of-34-sale-as-is/agora-405863"><meta property="og:image" content="https://…/_og/d/c_Product.takumi,themeKey_AgorastoreEquipment,headline_~Q2hyaXN0bWFzIGxpZ2h0…"><link rel="preload" as="style" href="/_nuxt/entry.CvIfEjar.css"><link rel="modulepreload" href="/_nuxt/DZT0-XG2.js"><link rel="modulepreload" href="/_nuxt/B4qJt7x1.js"> …94 more head elements… <script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Product","name":"Christmas light decorations – Set of 34 - Sale as is","image":["https://d788mwuyukqin.cloudfront.net/en/resources/pictures/…"],"offers":{"@type":"Offer","priceCurrency":"EUR","availability":"https://schema.org/InStock"…</script></head><body><div id="__nuxt"><div class="app-layout"><header class="app-header"><nav aria-label="Main navigation"><ul class="nav-list"><li><a href="/en/catalogue">Catalogue</a></li><li><a href="/en/auction-calendar">Auctions</a></li> …the entire header, gallery, breadcrumbs, similar-products grid, footer — ≈4,300 elements… <script>window.__NUXT__={data:{"item-agora-405863":{"itemShortId":"agora-405863","status":"CLOSED","translations":[{"language":"en","name":"Christmas light decorations – Set of 34 - Sale as is","description":"Set of Christmas light decorations, from the municipal equipment…"}],"relatedResources":{"pictures":[{"resourceReferenceId":"TmK7x7Fge-O1TXmIo07a2"},{"resourceReferenceId":"AQV_w6r0ZKkOTWB8C0xCz"}]},"category":{"categoryShortId":"7gWHBAAwREpxpyGfulLTj","translations":[…]},"indexedMeta":{"info":{"country":"FR","postalCode":"37800"},"saleInformation":{"numberOfBids":0,"currency":"EUR","pricesCents":{"start":20000,"current":null,"reserve":null}},"seller":{"organisationShortId":"…","name":"Commune de Sainte-Maure-de-Touraine"}}},"similar-agora-405863":[{"itemShortId":"agora-401815","translations":[…]},{"itemShortId":"agora-399204",…}]},state:{"$snuxt-seo-meta":{…}},once:new Set(),_errors:{}}</script> …hydration payload continues for another ~120 KB…
what a scraper must ingest — the price is in there, somewhere
GET /…/agora-405863.mdtext/markdown · 3.8 KB · ≈1,000 tokens
--- title: "Christmas light decorations – Set of 34 - Sale as is | Agorastore" canonical_url: https://…/agora-405863 locale: en description: "Other accessories, FR. Buy at the best price and bid online on Agorastore." --- # Christmas light decorations – Set of 34 - Sale as is Session: [Daily Sale](…/auction/daily-sale…) Sainte-Maure-de-Touraine (37800) · France ## Sale information Starting Price : **€200** Status: Closed · No bids ## Further information Product type: Bright decoration Description: Set of Christmas light decorations, from the municipal equipment: 12 “star”, 14 “snowflake”, 8 “golden flowers”. Old lighting system (non-LED), used condition. General condition: Used, not recently tested ## Payment terms Payment within 7 days to the Public Treasury. ## Withdrawal procedures Pick-up within 14 days on site, at the buyer's expense. …images, seller context and similar lots follow — 3.8 KB total…
what GPTBot receives — negotiated automatically
67×
smaller payload — 255.5 KB → 3.8 KB, same facts
≈1k
tokens instead of ≈64,000 — cheaper, faster, more accurate agent answers
0 JS
nothing to execute or render — plain text an agent reads directly
1 URL
content negotiation on the same route — no shadow site to maintain

Both payloads are the live captured responses for product agora-405863 on build 849 (token estimate: ~4 characters per token). The Markdown keeps everything that matters — title, price, characteristics, dates, seller terms, images and the canonical link back to the page — and drops everything that doesn't.

08 · Social previews

Every shared link is now a branded storefront.

Paste a marketplace link in LinkedIn, Slack or WhatsApp. On V1 you got a bare logo — or a raw warehouse photo with no context. V2 renders a designed 1200×630 card live for every page, in the right brand, with title, category and price composed in. Try any combination — every V2 image below is the deployed renderer's real output:

Platform
Page
Brand (V2 renders per-tenant)
V1 · oldSITE LOGO / RAW PHOTO
V2 · newLIVE-RENDERED 1200×630
Nothing here is a mockup of the cards themselves. The eight V2 preview images were downloaded from the deployed build's own OG renderer (/_og/…) — four page types × two brands, each generated on request, in the tenant's colors, with a graceful logo fallback when a product has no photo.
09 · Accessibility

A perfect automated score — on every single page.

Accessibility is not a page-by-page patch job on V2 — semantic structure, naming and contrast are owned once, by the shared component system. The automated result speaks for itself:

77–89
V1 · varies by page and form factor
invalid ARIA attributes unnamed buttons & links contrast failures label / name mismatches broken heading order
0
V2 · all six page / form-factor combinations
zero automated failures one H1 per page consistent semantic baseline

An automated 100 is a strong floor, not a conformance claim: keyboard traversal, screen readers, zoom/reflow and reduced-motion are on the checklist for the full 50-product study.

10 · The launch plan

The platform is done. Here's the plan to let it breathe.

One honest finding remains: with the shared third-party stack enabled, V2 loses 8 desktop and 23 mobile Lighthouse points (+1.25 MB, +28 requests on every cold page). The marketplace is no longer the bottleneck — the tag stack is. The plan attacks exactly that, in order — and step 2 has already shipped:

1

Replace Didomi with a lightweight open-source consent layer

CookieConsent v3 — MIT-licensed, a few kilobytes, fully themeable — replaces the tool whose own banner becomes the page's largest paint (~16 s LCP on throttled mobile). Tracking and telemetry stay, consent-gated exactly as today; what disappears is the cost of the tool itself, which currently butchers every metric it sits in front of. Includes a one-for-one legal review of the consent taxonomy.

today: consent UI = the measured LCPafter: same legal behavior, ~zero weight

Load GTM only after the page is measuredShipped · PR #158

Done. GTM is now an optional runtime off the critical rendering path: application code pushes events immediately into a private queue, consent stays the trigger for capture, and once granted the container is only requested after web-vitals finalizes the initial LCP. No event is lost — only enqueued — and an untouched Lighthouse run never fetches, parses or executes GTM at all.

no event lost — only enqueuedconsent still gates captureGTM off the critical path
3

Chat loads on intent, not on load

The chat widget currently ships over 0.5 MB and ~0.095 CLS into the critical path of every visit. It moves to interaction-or-idle loading, with reserved geometry for the launcher so nothing shifts when it arrives.

4

Finish the product route on mobile

Product scores 70 on mobile with a 7.71 s gallery-image LCP — 49% faster than V1, but behind the 88 of home and catalogue. Prioritizing the first gallery image is a focused, known fix — not an architecture problem.

5

The 50-product study & production probes

The final validation: 25 legacy + 25 canvas-rich products — metadata completeness, structured-data validity, content parity — plus the full crawler matrix re-run against the production edge, without UAT's Basic Auth in the way.

Steps 1–3 recover the points the tag stack costs today — none of them touch marketplace code, and the GTM half is already done. The application-controlled numbers in this report are what production users get once the stack is cleaned.