If your application renders client side, AI crawlers are probably receiving an empty document. This is a rendering architecture problem rather than a content problem, and the fix lives in your build configuration rather than your CMS.
Diagnose before you refactor
Fetch your own page the way a crawler does, without a browser engine:
curl -A "GPTBot" https://yoursite.com/your-page -o page.html
Then count the words in the body:
sed -e 's/<[^>]*>//g' page.html | tr -s ' \n' ' ' | wc -w
Under a hundred words on a content page means the document you are serving is a shell. Compare that against the same page in a browser to see the gap.
Route selection
Static generation builds HTML at deploy time. Fastest possible delivery, no server rendering cost per request, and the right answer for marketing pages, documentation and blogs where content does not vary per user. In Next.js this is generateStaticParams with default static rendering. In Nuxt it is nuxt generate. In SvelteKit it is the static adapter with prerender enabled.
Server rendering builds per request. Necessary when content is personalised or changes frequently. Costs server time per request, so cache aggressively at the edge.
Selective prerendering serves prebuilt snapshots to bots by user agent while humans continue to receive the SPA. Pragmatic when a full migration is not realistic, though it introduces a divergence between what bots and users see, which needs care to avoid looking like cloaking. Keep the content identical and only the delivery mechanism different.
The parts people miss
Streaming and suspense boundaries. Server rendering with heavy suspense can still deliver a shell for the content that matters if the important component is inside a boundary that resolves late. Check what is in the initial flush rather than assuming the framework handles it.
Client-only data fetching in server components. Mixing patterns leaves you with a technically server-rendered page whose actual content still loads in an effect. The audit is the same: read the raw HTML.
Structured data injected by script. JSON-LD added through a client-side tag manager is not in the served document. Put schema in the server response.
Meta tags set dynamically. Title and description assigned by a client-side head manager may be absent from the initial HTML. Framework head APIs that run server side solve this.
Verify after deploying
Rerun the curl test. Then confirm the important elements survive: title, meta description, H1, body copy, JSON-LD. If any are missing, they are still being added after delivery.
A free browser-based version of this analysis is at JavaScript Rendering Checker if you would rather paste the source than run shell commands, and the wider treatment of SSR for AI crawlers covers the strategy side.
Why this is worth doing now
Search engines that render JavaScript have made client-side rendering survivable for a decade. Retrieval systems that do not render have made it costly again. The remedy is the same one that improves your Largest Contentful Paint, so the performance case and the visibility case point the same direction.
Top comments (0)