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.
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
Empty HTML for the crawler: the command above returns a container with no text. It's the main symptom and the one Google describes as a risk on JavaScript sites.
Made-up routes that answer 200: request a URL that doesn't exist and look at the status code. If it answers 200 with the home page, Google treats it as a soft 404 and may index it as a duplicate.
Temporary redirects where permanent ones belong: Google consolidates signals through a 301; a 302 tells it the move is provisional.
A sitemap that lists noindex or nonexistent pages: a sitemap should only carry indexable, canonical URLs. One that contradicts the site is worse than none.
Titles defined in three places that don't match: the platform's SEO panel, the code and the template. Google picks one and may pick a canonical you didn't expect.
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.
- JavaScript SEO basics · Google Search Central
- HTTP status codes, network and DNS errors (soft 404) · Google Search Central
- Redirects and Google Search · Google Search Central
- Build and submit a sitemap · Google Search Central
- How to specify a canonical with rel=canonical and other methods · Google Search Central
- Introduction to structured data markup · Google Search Central
- Custom Domains for Workers · Cloudflare Docs
- URL Inspection Tool · Google Search Console Help