Why Is My React SPA Not Indexed by Google?

Updated 19 Oct 2026

Check your app now: free 30-second health check

Paste your live URL. We'll show what visitors and Google actually see. No signup.

Passive check only. We never submit forms or log in.

Most apps built with Lovable (older projects), Bolt, v0 exports and many Cursor projects are single-page applications built with React and Vite. When you request the page, the server sends back an almost empty HTML file. JavaScript then builds everything you see. That's fine for users, but it adds risk for search engines.

How Google handles JavaScript pages

According to Google Search Central's JavaScript SEO basics, Googlebot works in stages:

  1. It crawls the URL and reads the raw HTML.
  2. It queues the page for rendering. When resources allow, a headless Chromium runs your JavaScript.
  3. It indexes the rendered HTML.

So Google can index SPAs. The rendering step can be delayed, though, and anything that breaks during it leaves Google with an empty page.

The common reasons SPAs don't get indexed

1. The rendered page is empty or broken

Anything that stops your JS from running stops Google seeing content:

  • a JS error
  • a blocked script
  • an API call that fails from Google's servers
  • content that only appears after user interaction

Check: Search Console → URL Inspection → Test live URL → View tested page. Look at the HTML and the screenshot.

2. Every route has the same title and description

If index.html hardcodes one <title> and you never update it per route, Google sees many URLs with identical metadata. It may pick one and skip the rest. Use a head manager (or your framework's metadata API) to give each route a unique title, description and canonical.

3. Links aren't real links

Google discovers pages by following <a href="/page"> links. Navigation built with onClick handlers on divs or buttons can't be followed. Use real anchor tags, e.g. React Router's <Link>, which renders them.

4. Hash URLs

Routes like /#/pricing are treated as one URL. Use the History API (BrowserRouter) with an SPA fallback on your host.

5. Soft 404s

An SPA typically returns HTTP 200 for every path, even ones that don't exist, so Google may flag "soft 404s". For unknown routes, set <meta name="robots" content="noindex">, or serve real 404 status codes with SSR or edge rules.

6. Blocked resources

If robots.txt disallows /assets/ or your API domain, Google can't render the page. Allow the JS and CSS files your page needs.

7. No sitemap and no links

A new SPA with no sitemap and no inbound links gives Google nothing to start from. Submit sitemap.xml in Search Console.

Fixes that work, from least to most effort

  • Fix render-blocking errors and add unique per-route metadata.
  • Pre-render static routes at build time. Landing, pricing and blog pages get real HTML.
  • Use your platform's crawler pre-rendering. Lovable's docs say older React + Vite apps get on-request pre-rendering for verified crawlers.
  • Move to SSR, e.g. Next.js, Remix, TanStack Start or Astro. Per Lovable's docs, Lovable apps created from May 13, 2026 use TanStack Start with SSR.

Google describes "dynamic rendering" (serving bots a different version) as a workaround rather than a long-term solution. Prefer SSR or static pre-rendering.

How FlowCanary's free check detects this

FlowCanary compares two views of your homepage:

  • the raw HTML a crawler receives, fetched with a Googlebot user agent
  • the rendered page after JavaScript runs in a real browser

If the raw HTML has almost no text while the rendered page is full, you'll see a clear "Google may see a blank page" warning. The scan also flags:

  • console errors that could break rendering
  • a missing title, description, canonical or og:image on your homepage
  • noindex tags
  • robots.txt blocks and a missing sitemap

Each finding includes a paste-ready prompt to fix it in your AI builder.

See what Google sees, free, in 30 seconds →

FAQ

Does Google index client-side rendered React apps?

Yes, it renders JavaScript. But rendering is a separate, sometimes delayed step, and errors during it can leave pages unindexed.

Do other search engines and AI crawlers run JavaScript?

Support varies, and many AI crawlers fetch raw HTML only. Server-rendered HTML is the safest choice.

Is `react-helmet` enough?

It sets per-route tags after JavaScript runs, which helps with Google. Pre-rendering or SSR also makes those tags visible to crawlers that don't run JS.

Related guides

Run the free 30-second check

Back to the FlowCanary homepage