cd /news/developer-tools/how-to-make-a-website-that-chatgpt-a… · home topics developer-tools article
[ARTICLE · art-61743] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

How to Make a Website That ChatGPT Actually Cites: Schema, llms.txt, and AEO for Developers

A developer outlines a practical checklist for making websites citeable by AI search systems like ChatGPT, Perplexity, and Google AI Overviews. The guide covers unblocking AI crawlers in robots.txt, implementing the llms.txt convention, adding structured data markup (LocalBusiness and FAQPage), and structuring content for answer extraction. The developer emphasizes that machine-readability is now a developer's responsibility, not just an SEO concern.

read5 min views1 publishedJul 16, 2026

Your client's site is fast, accessible, and ranks fine on Google and ChatGPT has never heard of it. That's not an SEO problem. It's a machine-readability problem, and as the developer, you're the one who can fix it. This is the practical checklist I use, with copy-paste code.

Why this is now a developer's job

AI search systems (ChatGPT search, Perplexity, Gemini, Google AI Overviews) don't rank pages they retrieve and synthesize. A page enters the retrieval pool only if crawlers can fetch it, parse it, and extract unambiguous facts from it. Rendering strategy, structured data, crawl directives that's our layer, not the marketing team's.

Three failure modes cover most invisible sites: AI crawlers blocked in robots.txt, facts locked inside JavaScript or images, and zero structured data. All three are fixable in an afternoon.

Step 1: Stop blocking the crawlers (2 minutes) Check yourdomain.com/robots.txt. Security plugins and copy-pasted "protect my content" configs routinely block the exact bots that power AI search:

txt# BAD - makes you invisible to AI search

User-agent: GPTBot Disallow: /

User-agent: PerplexityBot Disallow: /

Know the distinction: search/browse bots (OAI-SearchBot, ChatGPT-User, PerplexityBot, Claude-SearchBot) fetch pages to answer live queries — block these and you vanish from AI answers. Training bots (GPTBot, Google-Extended, ClaudeBot) collect training data. If the client has IP concerns, block training, allow search:

txt# Reasonable middle ground

User-agent: GPTBot Disallow: /

User-agent: OAI-SearchBot Allow: /

User-agent: PerplexityBot Allow: /

User-agent: ChatGPT-User Allow: /

Default recommendation for local businesses: allow everything. Being cited is the whole game.

Step 2: Ship an llms.txt (15 minutes) llms.txt is an emerging convention (adopted by Anthropic, Cloudflare, Zapier, Stripe among others): a markdown file at your root that tells language models what the site is, in plain text they can't misparse. Adoption by crawlers is still uneven treat it as cheap insurance, not magic:

markdown# Acme Furniture Rawalpindi

Custom furniture workshop in Rawalpindi, Pakistan.

Handmade sofas, beds and office furniture since 2011.

Serve it as text/plain or text/markdown at /llms.txt. One file, zero build changes.

Step 3: Structured data that actually matters (the big one) Schema markup is the highest-leverage item on this list. There's documented enterprise data of AI Overview accuracy jumping from 43% to 91% after proper entity-linked schema. For a local business, the minimum viable set is LocalBusiness + FAQPage:

html<br>

{<br>
"[@context](https://dev.to/context)": "<a href="https://schema.org">https://schema.org</a>",<br>
"@type": "LocalBusiness",<br>
"name": "Acme Furniture",<br>
"description": "Custom furniture workshop in Rawalpindi, Pakistan.",<br>
"address": {<br>
"@type": "PostalAddress",<br>
"streetAddress": "Main Murree Road",<br>
"addressLocality": "Rawalpindi",<br>
"addressCountry": "PK"<br>
},<br>
"telephone": "+923000000000",<br>
"url": "<a href="https://example.com">https://example.com</a>",<br>
"openingHours": "Mo-Sa 10:00-20:00",<br>
"sameAs": [<br>
"<a href="https://www.facebook.com/acmefurniture">https://www.facebook.com/acmefurniture</a>",<br>
"<a href="https://www.instagram.com/acmefurniture">https://www.instagram.com/acmefurniture</a>"<br>
]<br>
}<br>

Rules that matter in practice: the JSON-LD must agree exactly with the visible page (AI cross-checks); sameAs links are your entity-disambiguation lifeline; and FAQ answers in schema must be verbatim copies of the on-page text, not summaries.

Step 4: Answer-first content structure AI extraction favors pages where the answer appears in the first 40–60 words under a question-shaped heading. Work with whoever writes the content to enforce this pattern:

html

A custom three-seater sofa in Rawalpindi typically costs PKR 45,000-120,000 depending on wood and fabric. Below is the full price breakdown...

Direct answer, then depth. Tables beat paragraphs for comparisons LLMs parse them cleanly. And render critical facts as server-side HTML: if the price only exists after a client-side fetch, assume AI never sees it.

Step 5: Entity consistency (the invisible killer) LLMs resolve conflicting facts by consensus. If the site says +92 300 1111111, Google Business Profile says 0300-2222222, and a directory says a third number, the model picks one — possibly none. Audit name/address/phone across every surface and make them byte-identical where possible. Boring, decisive.

Verification loop

After shipping: fetch your pages as the bots do (curl -A "PerplexityBot" and check what HTML comes back), validate schema at validator.schema.org, then actually ask ChatGPT/Gemini/Perplexity the category question ("best custom furniture in Rawalpindi") weekly and log whether your client appears. Retrieval-grounded answers typically reflect fixes in 2–5 weeks; training-data errors take longer and need the consensus fix above.

Step 6: Get indexed where AI actually looks

A corrected page the crawlers haven't fetched fixes nothing. Two indexes matter more than most devs realize:

Bing is load-bearing. ChatGPT search and Copilot are substantially Bing-grounded. Register the site in Bing Webmaster Tools (you can import straight from Google Search Console), submit the sitemap, and check site:yourdomain.com on Bing. A site missing from Bing is invisible to a large slice of AI search regardless of how good its Google presence is.

IndexNow is free and instant. One ping tells Bing (and everything downstream of it) about new or updated URLs:

bashcurl "https://api.indexnow.org/indexnow?url=https://example.com/updated-page&key=YOUR_KEY" Generate a key, drop the key file at your root, and wire the ping into your deploy pipeline so every content update propagates automatically. For WordPress clients, several SEO plugins now ship IndexNow support — flip it on.

Edge cases that bite

SPAs and client-side rendering: if curl returns an empty shell, assume AI retrieval sees an empty shell. Server-render or pre-render anything you want cited. Cloudflare bot rules: Bot Fight Mode and aggressive WAF configs silently 403 AI crawlers — check the firewall event log for the user agents above before blaming content. Multilingual sites: keep the facts identical across language versions; models cross-reference them and conflicting details (different phone numbers on /en/ vs /ur/) reads as inconsistency, not localization.

The bigger picture

This checklist is the technical half of a discipline called AEO/GEO (Answer Engine Optimization / Generative Engine Optimization) the other half is brand authority, reviews, and citations, which is marketing's territory. If you want the complete picture including the non-technical layer and how to evaluate whether an agency actually knows this stuff, I've linked the full guide here:

If you want to automate the verification loop, a cron job that snapshots your key pages as each bot sees them is twenty lines of code and catches regressions before they cost citations: bash#!/bin/bash

for UA in "OAI-SearchBot" "PerplexityBot" "ChatGPT-User"; do

curl -s -A "$UA" [https://example.com/](https://example.com/) -o "snap-$(date +%F)-$UA.html"

grep -c "your-phone-number" "snap-$(date +%F)-$UA.html" || echo "WARN: $UA cannot see key facts"

done

Diff the snapshots week over week. The day a plugin update or a WAF rule silently breaks crawler access, you'll know that week — not three months later when the client asks why the leads dried up.

Ship the robots.txt fix today. It's two minutes, and it's probably the highest ROI-per-line-of-config you'll touch this month.

── more in #developer-tools 4 stories · sorted by recency
── more on @chatgpt 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-make-a-websit…] indexed:0 read:5min 2026-07-16 ·