Humans hate text. AI needs it.

Readers skim, so we build pages out of visuals. But the crawlers behind ChatGPT and Claude read raw HTML only — no JavaScript, no images, and not even your schema. Here is how to build for both without compromising either.

Share
SeeIndie banner: Humans hate text. AI needs it.

Every piece of advice about writing for the web says the same thing: people don't read, they skim. So we stopped shipping walls of text and started building pages out of cards, tables, stat bands and steps. This site does it on every page, on purpose. Then the machines showed up — and they want the exact opposite.

Where this sits. This is the build side of the argument in AI search visibility won't sell your indie game. The strategy question — whether any of this brings you wishlists — is answered there. This post is about what you actually ship. The wider context is in indie game marketing basics.
28%
of the words on a page, at most, get read in an average visit
Nielsen Norman Group
0
JavaScript executions across 500M+ GPTBot fetches
Vercel / Merj
5 of 5
models missed product data that lived only in JSON-LD
searchVIU, via SEJ
2
major AI crawlers do render JavaScript: AppleBot and Gemini
Vercel / Merj

Readers really do skim

This part isn't controversial. Nielsen Norman Group has been measuring it for two decades: on an average visit, people read at most about 28% of the words on a page, and the realistic figure is lower. Eye-tracking shows the F-pattern — first lines, left edge, gone.

For an indie dev that's not an abstraction. Someone clicks through from a Reddit comment. You have a few seconds before they're back in the thread. A wall of text loses them; a screenshot, one line of hook and a wishlist button keeps them.

And you don't have to take Nielsen's word for it. Put a heatmap on your own site and watch it happen: Microsoft Clarity is free with no traffic limit and gives you scroll maps, click maps and session recordings. PostHog and Hotjar do the same on a free tier. I put Clarity on this site before I wrote a single post, for exactly this reason — more of them are in the free and cheap tools list.

Open the scroll map on your longest page and find the depth where the line falls off a cliff. On most game sites it's in the first third. That number is how much of your careful prose is actually being read.

Two views of the same page. The heatmap tells you what your readers skipped. view-source: tells you what the machines never saw at all. You need both, and most people are only looking at the first one — if that.

So building visually is right. I'm not walking that back. The problem is what we build the visuals out of.

The machines don't skim. They can't even see.

A growing share of the people who ever hear about your game will hear about it from a model — someone asking for "colony sims like RimWorld but smaller", a journalist checking who made the thing, a publisher's analyst doing a first pass. Those crawlers read your page very differently than Google does.

Vercel and Merj analysed over a billion crawler requests. GPTBot fetches your JavaScript files. ClaudeBot fetches them too. Neither one runs them. Across more than 500 million GPTBot fetches: zero JavaScript executions. Whatever your framework renders on the client does not exist as far as those two are concerned.

What a reader sees
Your hero, your trailer, your feature cards, your FAQ accordion

Rendered in the browser, after your JavaScript runs.

What GPTBot gets
<div id="root"></div>

The server's raw HTML. If your content isn't in it, the model never saw your game.

The honest version of that finding, because it cuts both ways:

CrawlerRenders JavaScript?Why it matters
GPTBot (ChatGPT)NoThe one people actually ask about your game
ClaudeBotNoFetches your JS files, never executes them
PerplexityBotNoRaw HTML only
AppleBotYesBrowser-based crawler, like Googlebot
GeminiYesRuns on Google's crawling infrastructure
GooglebotYes, but lateSecond rendering wave — fine for a blog, bad for a launch week
So it isn't a law of nature. "AI can't read JavaScript" is too strong. It's "the two crawlers behind ChatGPT and Claude don't" — and for an indie game, those are the two that matter.

And no, your schema doesn't save you

This is the fallback everyone reaches for: fine, the visible page is JavaScript — but I put everything in JSON-LD, so the machines have it.

searchVIU ran the controlled version of that experiment. They placed product data only in JSON-LD markup, nowhere in the visible text, then asked the models about it. ChatGPT, Claude, Perplexity, Gemini and Copilot — all five missed it. At live retrieval, structured data gets treated as exactly what it is: a script tag the model wasn't reading.

Not a delivery mechanism
"My content is in the schema, so the AI has it."

Five models, one controlled test, zero pickups. Ahrefs found the same at scale: across 1,885 pages, schema markup produced no measurable lift in AI citations. Keep schema — it earns you rich results in Google, and it's cheap. Just don't hide content in it.

Late is not never — but it's still late
"Google renders JavaScript, so I'm fine."

Google renders in a second wave, days after the first crawl. Tolerable for an evergreen guide. A bad bet for a launch week. And it says nothing about GPTBot or ClaudeBot, which don't render at all.

Alt text is one sentence carrying twelve
"The comparison is in the infographic."

A model sees <img src="comparison.png"> and learns nothing. Every number you baked into that export is invisible. The image sells the game to a human; it tells a machine nothing at all.

If it isn't in the HTML your server sends, it doesn't exist. Not in JavaScript. Not in an image. Not in your schema. In the HTML.

What a visual component made of text looks like

This is the whole trick, and it's less clever than it sounds. Take a comparison of two things. The bad version is a designed image: beautiful, on-brand, exported from Figma, completely opaque. The good version is a table — or two divs with headings and list items — styled with CSS until it looks like the image did.

Same visual weight for the human. But now every number, label and caveat is real text in the delivered HTML. The reader skims the layout. The machine reads the words. Nobody compromises.

  • Stat bands are divs with a number and a label — not a graphic with the numbers baked in.
  • Comparison cards are semantic markup plus CSS — not an exported PNG.
  • Step boxes are an ordered list that got styled — not a flowchart image.
  • Accordions and tabs hide content visually; the text still ships in the HTML. Check yours — some component libraries mount the panel content only on click, and that content is gone.
  • Charts are the honest exception. If it has to be an image, write the finding underneath it as a sentence. The chart illustrates; the sentence is the content.

Every visual element on this page is built that way. Not because it's elegant — because I'd rather not argue for a rule while breaking it in the same breath.

Test it in ninety seconds

1
View source

Not the Elements panel — that shows the DOM after your JavaScript ran, which is the thing you're testing. Use view-source: and search for a sentence you care about.

2
Turn JavaScript off

Reload. What survives is roughly what GPTBot and ClaudeBot get.

3
curl your own URL

It's ugly, and it's the truth. If the page comes back as an empty root div, no amount of schema, llms.txt or AI-SEO tooling will fix it.

What I'd actually do

1
Server-render anything that carries meaning

Framework choice is yours. The requirement isn't.

2
Rebuild your "visual" components out of real markup

Text and CSS, not exported images. Start with the page you'd want a model to summarise correctly — usually the one about your game.

3
Write the finding as a sentence next to every chart or screenshot

One line. That's the line that gets quoted back to someone asking about your game.

4
Keep the schema. Expect nothing from it.

It's plumbing, not distribution.

None of this makes your page uglier — that's the part I'd underline. The tradeoff people assume they're making, readable for humans or readable for machines, isn't real. It only becomes real if you build your visuals out of pixels instead of words.

Common questions

Do AI crawlers execute JavaScript?
Mostly no. Vercel and Merj found that GPTBot (ChatGPT) and ClaudeBot fetch JavaScript files but never execute them — zero executions across more than 500 million GPTBot fetches. AppleBot and Gemini are the exceptions: both render JavaScript, because Gemini runs on Google's crawling infrastructure.
Does structured data help my page get cited by AI?
Not on its own. A searchVIU experiment placed product data exclusively in JSON-LD, and ChatGPT, Claude, Perplexity, Gemini and Copilot all missed it. Ahrefs found no measurable lift in AI citations across 1,885 pages. Keep schema for Google's rich results — don't use it as a hiding place for content.
Isn't Google able to render JavaScript anyway?
Yes, but in a second wave, and later. That's a tolerable delay for an evergreen post and a bad bet for a launch week. It also says nothing about ChatGPT or Claude, which don't render at all.
Does this mean I should stop using images on my game's site?
No. It means an image shouldn't be the only place a fact lives. Screenshots and trailers sell the game to humans; a sentence next to them tells the machine what it's looking at.
How do I check whether my content is actually visible to AI crawlers?
Use view-source: on your URL, or curl it, or disable JavaScript and reload. Whatever's left is roughly what an AI crawler sees. The DevTools Elements panel won't tell you — it shows the page after your scripts have run.

Sources