Skip to content

Single page application SEO: how Google reads your app and how to fix it

By Carlos Alberto Cardona B. · · 9 min read

A single page application looks complete in the browser and can reach Google empty. Google's own JavaScript SEO guide says the crawler renders JavaScript in a second pass, with limited resources, and recommends not depending on that pass for important content.

This guide comes from two sites I built and measured on an AI platform (Base44), one of them a documented case study with the Search Console curve. Every point comes with the command to check it on your own site.

What Google actually gets from an SPA

React, Vue, Next.js in client mode, Lovable, Base44 and most AI builders generate one nearly empty HTML file plus a JavaScript program that draws the content once it runs in the browser. The first response the crawler receives is the empty file.

$ what Googlebot receives from a freshly published app
curl -s -A "Googlebot" https://your-site.com/services | head -c 400<title>Home</title><div id="root"></div>→ the home title and an empty container, on EVERY route

The five symptoms I check first

$ all five, from your terminal
curl -s -A "Googlebot" https://your-site.com/ | wc -w                  # words Google receivescurl -s -o /dev/null -w "%{http_code}" https://your-site.com/nope       # must be 404curl -sI https://your-site.com/page/ | grep -i "HTTP\|location"        # 301 to the URL without slashcurl -s https://your-site.com/sitemap.xml | grep -c '<loc>'             # how many URLs?curl -s -A "Googlebot" https://your-site.com/ | grep -o "<title>.*</title>"

How to fix it without leaving your platform

You don't need to rewrite the site. You need the HTML that arrives in the first byte to carry the content, and something in front of the site that answers real 404s and 301s.

  • Prerender: at build time, generate one HTML file per route with the real text, the metadata and the structured data. Google reads the page without executing anything. If an H1 doesn't match or code leaks in, the build fails.

  • A Cloudflare Worker as a custom domain in front of the platform: it rewrites each route to its prerendered HTML, returns a real 404 for anything outside the manifest and handles the 301s. Cloudflare documents Custom Domains.

  • One source of truth for titles, descriptions and structured data, in the code, with an automated check that warns if any copy drifts.

  • Verification in production with the Googlebot user agent after every publish, and Google's URL Inspection to confirm what it actually indexed. What a dashboard says is not evidence; the server's response is.

What I don't claim

I haven't measured Lovable, Next.js in server mode or Webflow with this exact method, so I don't compare them. When I do, this section will say what their server answers to Googlebot, with a date. Until then, the five commands above work for any builder.

If you'd rather have me check it, the free diagnosis starts with exactly these five symptoms. How I work, including what I never change without approval, is in the portfolio and the Cayu case, the tool I use to audit it.

Sources

Consulted on September 19, 2026. Each date is the source's last published update.

  1. JavaScript SEO basics · Google Search Central
  2. HTTP status codes, network and DNS errors (soft 404) · Google Search Central
  3. Redirects and Google Search · Google Search Central
  4. Build and submit a sitemap · Google Search Central
  5. How to specify a canonical with rel=canonical and other methods · Google Search Central
  6. Introduction to structured data markup · Google Search Central
  7. Custom Domains for Workers · Cloudflare Docs
  8. URL Inspection Tool · Google Search Console Help

Is your site a single page application?

I check for free what Google receives from it and send you the findings in writing.

Get a free diagnosis