Every AI assistant reads a different web. I counted the citations in 141 answers A developer ran the same 47 buying questions through ChatGPT, Perplexity and Google AI Mode on the same day and classified every citation across the resulting 141 answers, finding Perplexity averaged 16.7 citations per answer versus 3.7 for Google AI Mode and 1.6 for ChatGPT. The study also found that all 507 Google Maps links ChatGPT produced were constructed search queries rather than real listings, and that JSON-LD injected via Next.js next/script never appears in server HTML, leaving structured data invisible to non-JavaScript fetchers. I put the same 47 buying questions to ChatGPT, Perplexity and Google AI Mode on the same day, and classified every citation across the resulting 141 answers. The engineering-relevant part of the result is not the ranking. It is how differently the three engines behave as clients of your site. Citations per answer. Perplexity 16.7, Google AI Mode 3.7, ChatGPT 1.6. Perplexity cited provider websites 667 times across its 47 answers. ChatGPT cited them 47 times, almost exactly one per answer. That gap is the whole engineering brief. Against Perplexity, the page you ship is genuinely in play: it reads widely and shows its work. Against ChatGPT, at roughly one site per answer, selection happens before your page is read, and no amount of on-page work changes the shortlist you were not on. A trap worth naming. ChatGPT referenced Google Maps in 23 of 47 answers, which reads as an argument for a verified business listing. It is not. All 507 Maps links were of the form google.com/maps/search/Name,+City , a constructed query. Links to actual listings, /maps/place/ , numbered zero. The model finds the provider by ordinary web search and renders the map link as an affordance. Check link shapes before drawing a conclusion from a hostname. One implementation detail that surprised me while checking my own site. JSON-LD rendered through Next.js next/script does not appear in the server HTML at all, including with strategy="beforeInteractive" . The content is queued into self. next s and injected after hydration. Google executes JavaScript and gets there eventually. Most of the fetchers behind assistant answers do not. On one page I could see it directly: a FAQPage block emitted through a plain