The AI-built React + Vite site: a nice page that crawlers barely see

React with Vite is one of the most common outputs of AI app builders and coding agents, and by default it produces a client-rendered single-page app. The server sends an HTML file with a title, an empty root element and a script; the page itself is built in the browser. So the AI-built React + Vite site has two problems at once: it converges on the same layout and copy as other generated sites, and its copy is invisible to anything that does not run JavaScript, including the IntentGrid demo. Fix the second one first.

Last updated 2 October 2026.

Why AI-built React + Vite sites converge

Vite is a build tool and React is a UI library; neither has a look. The look arrives with the defaults.

  • The usual pairing: React, Vite, Tailwind, a component kit such as shadcn/ui and an icon set, chosen because models have seen them together most often.
  • Everything in one bundle. The landing page and the app share a component tree, so the marketing copy is written and reviewed as part of the app, which in practice means barely at all.
  • Copy written for no one, because the brief was about features.

These are easy to change. The rendering problem below decides whether anyone reads the copy at all.

What IntentGrid does and does not do for a React + Vite site

IntentGrid rewrites the visible copy for each visitor: headlines, body copy, feature descriptions and button labels, based on how they arrived. It adapts the copy you already have, and brand names, prices, dates and numbers stay as written. It needs that copy to exist in the HTML it receives.

It does not touch your code, your bundle or your hosting, it does not run JavaScript for you, and it does not change design. On a page whose HTML is an empty root element, there is nothing for it to rewrite.

Today the working part is a demo that renders a rewritten copy of a public URL in a sandbox on intentgrid.ai; adaptation on your own domain is early access, set up per site by hand. How it works has the full mechanism.

Client-rendered by default: what the HTML actually contains

A default Vite React app serves index.html for every route: the head you wrote, an empty root element and a module script. The demo fetches that file and strips the script, so it receives the shell and the preview comes back nearly blank. Any crawler that does not run JavaScript, including many AI crawlers, gets the same shell. Google renders JavaScript, so it can usually still index the page, with some delay.

Client-side routing adds a second trap. A deep link such as /pricing only works if your host sends every path to index.html; if it does not, the page loads fine when you click through to it and returns a 404 when someone opens the link directly. Open a deep link in a private window to check.

Three ways to get the copy into the HTML

Prerender the marketing routes. A prerendering step at build time renders the landing and pricing pages to static HTML, while the app stays a single-page app. This is usually the smallest change.

Move the landing page to a static site. Put the marketing pages in a static-first framework such as Astro, or in plain HTML, and keep the React app on its own path or subdomain.

Adopt server rendering. A React framework with server rendering solves it for every page, at the cost of a migration. Worth it for a content-heavy site, rarely for a single landing page.

An illustrative before and after

Illustrative example: a made-up browser-based photo editor, not a real site and not a recorded run.
Default, the same for everyone
Powerful photo editing, right in your browser
Arrived from a photography forum, on a laptop, in the evening
Edit RAW files in the browser, with nothing to install
Tapped a link in a shared video, on a phone
Fix the lighting on a photo in a few taps, on your phone

Same layout, same prices, same claims. Every version uses only what the original page already says: in this made-up case, RAW support, no install, and editing on a phone. On a client-rendered build, none of these headlines would reach the demo until the copy is in the HTML.

What to change first

In order:

  • Write a real title and meta description in index.html. For a client-rendered app it is often the only text crawlers and link previews ever see.
  • Get the landing page into the HTML, using one of the three routes above.
  • Make sure deep links work when opened directly, so shared links to /pricing or /docs do not 404.
  • Rewrite the hero yourself. Then ask your AI tool to list every other headline and button label, and rewrite the ones that could belong to any product.
  • Change the component kit's theme, the font and one stock section, so the page stops reading as the starter.

Why every generated site lands on the same defaults is covered in why vibe coded websites look the same.

React + Vite questions

Why does the IntentGrid demo show an empty page for my React + Vite site?

Because a default Vite React app is client-rendered: the HTML is a shell with an empty root element, and the page is built by a script. The demo strips scripts, so it only sees the shell. Prerender the marketing routes or serve them as static HTML, and the demo, like any crawler, can read the copy.

Can Google index a client-rendered React app?

Google renders JavaScript, so usually yes, though rendering can lag behind crawling. Many other crawlers, including many AI crawlers and link-preview bots, read only the initial HTML. For pages you want found and quoted, put the copy in the HTML.

Does IntentGrid run my JavaScript for me?

No. It works on the HTML a page serves. It does not run your app, and it cannot fix a page whose HTML has no copy in it. That fix is prerendering or server rendering, and it is worth doing whether or not you ever use IntentGrid.