Skip to content

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

By Carlos Alberto Cardona B.· · reviewed on 12 min read

Single page application SEO depends on one thing: that Google gets your text in the first HTML, not after JavaScript runs. Prerendering at build time puts it there without leaving your platform; server-side rendering does too, but usually means migrating. Two commands tell you whether your app needs it; on Base44 and older Lovable apps, use URL Inspection.

The same address requested twice, once as Googlebot and once as Chrome: 59,556 bytes both times, identical byte for byte. Measured on Sep 26, 2026 against the React app case study page.You don't sign off on prerendering by reading the code; you check it by requesting the page with both user agents and comparing. Serving different things depending on who asks has a name, and it isn't a compliment.

The essentials

What it is
React and Vue apps, Base44 and many AI builders make sites that look finished in the browser but can reach Google as an empty page.
Why it matters to you
If your site answers with an empty shell, to Google every page is the same empty page. It isn't ranking badly: it has nothing to rank.
What to do today
Run this guide's first command on your site and count the words that come back, or give your AI assistant the ten-minute prompt below. If there are almost none, confirm it with URL Inspection before changing anything.

Request your free diagnostic

I learned this on the first site I measured, a family member's. It looked complete in the browser, but Google received 24 to 35 words per page (Screaming Frog without JavaScript, Jul 18, 2026). Today it's case study 1 in my portfolio.

If you have already spent credits asking your builder to “improve the SEO” and nothing changed, the problem isn't the prompt. It's what Google receives.

A single page application (one page that JavaScript fills in) looks complete in the browser and can reach Google empty. Google's own JavaScript SEO guide says pages wait in a render queue until Google's resources allow. It adds that server-side or pre-rendering is still a great idea, because not all bots can run JavaScript.

Every point comes with the command to check it on your own site. It comes from two Base44 sites I specified, measured and fixed with AI agents.

If the page still isn't there afterwards, the seven causes of a page not appearing walk you through it in order. The Search Console guide is where you watch it land.

Haven't built it yet? Start with how to build a website with AI.

SPA SEO: what Google gets from a single page app

React, Vue, Next.js in client mode, Base44 and many AI builders work the same way. They generate one nearly empty HTML file plus a JavaScript program that draws the content once it runs in the browser. Unless the platform serves crawlers something else, their first response is that 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
A hand-drawn sketch of a web page on paper
Photo: Compagnons · Unsplash

What do I check first? The five symptoms

I check what Google receives first, not what I see on screen. There are five symptoms: empty HTML, made-up URLs that answer 200, temporary redirects, a sitemap that contradicts the site and titles that don't match. The first one is the main one, and I always start there.

  • Empty HTML for the crawler: the command above returns a container with no text. It's the main symptom and the one Google's JavaScript guide deals with.

  • 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 may treat it as a soft 404 or as a duplicate of the home page.

  • 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 sees the one that arrives in the HTML. If it doesn't describe the page, it builds its own from the H1 or other text.

One trap the browser won't show you: if the first HTML carries a noindex and the app removes it on load, Google may never notice. According to its JavaScript guide, when it sees a noindex it may skip running the code at all. What counts is what View page source shows, not what the page displays.

$ all five, from your terminal
curl -s -A "Googlebot" https://your-site.com/ | wc -w                  # words Google receives
curl -s -o /dev/null -w "%{http_code}" https://your-site.com/nope       # must be 404
curl -sI https://your-site.com/page/ | grep -i "HTTP\|location"        # 301 to the URL without slash
curl -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>"

From the browser · 2 min

What Google receives from your page

Why it matters: What you see on screen may not be in the code Google receives first. If the text only shows up when the browser assembles the page, Google depends on a second pass to read it.

From the browser · 3 min

The same thing, asking Google itself

Why it matters: If Google can't see the text on your page, it has nothing to show when someone searches for what you sell. Many AI-built sites assemble the text in the browser, and Google has to take an extra step to see it.

From the browser · 1 min

Whether your site has a real 404

Why it matters: If any invented address shows your home page, Google can store pages that don't exist and waste crawl time on them. A page that doesn't exist should answer with a 404 status, not with the 200 that means “all good”.

From the browser · 3 min

Whether an old URL leads to the new one, in a single hop

Why it matters: If you changed a URL and the old one doesn't permanently redirect to the new one, Google doesn't carry over what it had earned. And anyone arriving through an old link hits an error. A clean move answers 301, once, with no layovers.

From the browser · 3 min

Whether Google can follow your menu links

Why it matters: Google reaches your pages by following links. If your menu or buttons go to another page without being a real link, Google may never reach those pages. The same goes if the links only show up when someone opens a dropdown.

How do you fix it without leaving your platform?

You don't need to rewrite the site or leave your platform. You need the HTML in the first byte to carry the content, and something in front of the site that answers real 404s and 301s. It takes four pieces:

  • 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 (a small program in front of the site) as a custom domain. 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 isn't evidence; the server's response is.

If you can't put anything in front of your site, Google accepts two ways out for URLs that don't exist in a single page app. One: the app sends those URLs to a page that answers a real 404, say /not-found; two: your error page carries a noindex tag.

You can ask your AI builder for either, and then confirm it with the 404 check.

If you ask your builder: one change, and nothing else

An AI builder in a hurry fixes one thing and touches three. This is the order I follow when I hand a change to my agents, cut down to what you need:

Prompt for your builder: one change, and nothing else

Then run the check that found the problem again. If it comes out the same as before, the change didn't land, whatever the builder says.

If your builder promises “SEO included,” check what it includes in what Google receives, not in the editor's panel. While your site arrives empty, every month it's live is a month Google has nothing of yours to show. That's why the free diagnostic starts there, in writing within two business days.

A code editor showing React code
Photo: Juanjo Jaramillo · Unsplash

React SEO without Next.js: SSR, prerendering, and what to do if you can't migrate

A single page application isn't bad for SEO by itself: the problem is text that arrives late. What decides it is who builds the HTML, and when: each visitor's browser, your server on every request, or your build before you publish.

Google runs JavaScript, but its JavaScript SEO guide says server-side or pre-rendering is still a great idea. The page gets faster for users and crawlers, and not all bots can run JavaScript. These are the three ways to build the HTML:

ItemWho builds the HTMLWhen it fitsWhat to watch
Browser only (plain SPA)Each visitor's browser, when the JavaScript runsApps behind a login, where SEO doesn't matterThe first response carries an empty container for Google and for assistants
Server-side rendering (SSR)Your server, on every requestSites with many pages, or that change dailyIt needs a server that runs code; switching to it usually means migrating
Prerendering at build timeYour build, once per route, before publishingService sites with a few pages that change when you publishThat every route gets its HTML and none is left out

Vercel and MERJ measured it in 2024, across more than 100,000 Googlebot fetches. On nextjs.org, Google fully rendered every indexable HTML page; half waited 10 seconds or less, and some waited hours. In other words, Google does read the JavaScript, just late.

AI assistants are another story. In December 2024, the same team reported that “none of the major AI crawlers currently render JavaScript.” The exceptions it names are Gemini, which uses Googlebot's infrastructure, and AppleBot.

If showing up in their answers matters to you, that's what AI SEO covers.

React without Next.js: you don't have to migrate

If your site is React without Next.js, you don't need to switch frameworks for Google to receive the text. This site is React with Vite on Base44: every build generates one HTML file per route with the text, the metadata and the structured data. And the build fails if an H1 doesn't match.

I specified it, generated it with Claude Code, and verify it in production after every publish.

Rebuilding carries its own risk: when Pinterest rebuilt its pages, its SEO traffic took a few weeks to get back on par. Tags such as the H1 and the canonical were missing, according to its engineering blog (Mar 3, 2017). In the end it measured 40% less wait time, 15% more SEO traffic and a 15% higher signup conversion rate.

If you can't migrate or touch the build

  • Measure what Google receives today first, with the live test in URL Inspection. Your platform may already hand the content to crawlers, and there may be nothing to fix.

  • If you can put something in front of the site: a Worker that serves the prerendered HTML and answers real 404s and 301s. It's in the previous section.

  • Lovable says it prerenders only for crawlers on apps created before May 13, 2026 (June 22 on Enterprise plans). If your platform does that, it fits what Google calls dynamic rendering. Google describes it as a workaround, not a long-term solution: check it again after every big change.

  • If you can't do any of that, ask your builder for Google's two ways out for URLs that don't exist, from the previous section. They don't fix the empty content, but they stop made-up URLs from competing with the real ones.

Lovable and Base44 SEO: check what Google receives, whatever your builder does

Not every builder serves the empty shell you see in View page source. Lovable apps created before May 13, 2026 do; newer ones, according to Lovable, arrive rendered from the server. Base44 did when I measured it, between July and September 2026.

So I won't tell you Google can't see your site: I'll tell you to check what it receives, whatever your builder does.

I measured Base44 on two sites, and today it doesn't serve what it served then. Its documentation, read on Oct 18, 2026, says it serves crawlers a rendered version of each page. If that version isn't ready yet, it serves a short summary with the heading, the description and links.

That same day I requested nine routes of this site as Googlebot, on its free Base44 address and without the Worker. Six arrived complete; three came with a generic title and the home page text, and a made-up URL answered 200. In a regular browser, the three inner pages I tried showed the home page text.

Base44 says its SEO is designed for a custom domain, so yours may differ. That's why, on Base44 as on Lovable, View page source isn't enough: the test that counts is URL Inspection.

On Oct 18, 2026, its automatic sitemap and llms.txt included two pages this site marks noindex in its code: /gracias and /privacidad. According to its documentation, the dashboard lets you remove them from the sitemap one by one. With a prerender and a Worker in front, it's fixed.

According to Lovable's own documentation, re-read on Oct 18, 2026, apps created since May 13, 2026 are rendered on the server. Older ones get a pre-rendered version served only to verified crawlers such as Google's.

On those older apps, curl with a Googlebot user agent and View page source both show the empty shell, even if Google gets the content. So the test that counts there is the live test in URL Inspection, which Google runs from its own machines.

If Search Console lists your pages as “Discovered - currently not indexed” or “Crawled - currently not indexed”, those are different problems with different fixes. With the first, Google hasn't visited the page yet; with the second, it visited and didn't keep it. On an app that serves a near-empty page, that second status is the first thing I check.

The difference and what to do in each case are in the seven reasons a website doesn't show up on Google. It also explains why resubmitting the sitemap doesn't fix it.

No site yet, or about to rebuild it? I can build it with all of this solved from day one: see the SEO website design service. But first, see what a website costs if you hire someone.

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.

If you'd rather have me check it, the free diagnostic starts with exactly these five symptoms. How I work, including what I never change without approval, is in the portfolio. Once Google receives your site, setting up Google Analytics 4 tells you whether it brings in inquiries.

Fixing the render is the first step, not the last one. Once the crawler receives your HTML, the next questions are what it does with it: indexation, canonicals, structured data. Those are what a technical SEO audit covers.

And it's the same first step for AI answers: a page whose content never reaches the served HTML can't be cited by an assistant either. Which of the three layers you're failing, and which two you can check today, is in the guide on appearing in AI Overviews.

Watch it explained, by the people who built it

Two short videos from Google's own channels. They're the same source the links above point to, in video form:

Frequently asked questions

Sources

Article reviewed on October 18, 2026. Each date is the source's last published update.

See the 17 sources
  1. 01How Google Search indexes JavaScript sites · Google Search Central · video
  2. 02When does JavaScript SEO matter? · Google Search Central · video
  3. 03JavaScript SEO basics · Google Search Central
  4. 04Dynamic rendering as a workaround · Google Search Central
  5. 05HTTP status codes, network and DNS errors (soft 404) · Google Search Central
  6. 06Redirects and Google Search · Google Search Central
  7. 07Build and submit a sitemap · Google Search Central
  8. 08How to specify a canonical with rel=canonical and other methods · Google Search Central
  9. 09Introduction to structured data markup · Google Search Central
  10. 10Custom Domains for Workers · Cloudflare Docs
  11. 11URL Inspection Tool · Google Search Console Help
  12. 12Optimize your app for SEO and AI search · Lovable Documentation
  13. 13SEO and search visibility (read on Oct 18, 2026) · Base44 Docs
  14. 14Influencing your title links in search results · Google Search Central
  15. 15How Google handles JavaScript throughout the indexing process (Jul 31, 2024) · Vercel · Giacomo Zecchini, Alice Alexandra Moore, Ryan Siddle and Malte Ubl
  16. 16The rise of the AI crawler (Dec 17, 2024) · Vercel · Giacomo Zecchini, Alice Alexandra Moore, Malte Ubl and Ryan Siddle
  17. 17Driving user growth with performance improvements (Mar 3, 2017) · Pinterest Engineering · Sam Meder, Vadim Antonov and Jeff Chang

About the author. Carlos Alberto Cardona B., SEO specialist in Bogotá. I write what I measure, with every number next to its instrument and date, and I verify what AI executes myself.

Does your site look finished, but you can't tell what Google receives?

Send me the URL. In the free diagnostic I check what Google receives from your site. You get it in writing within two business days, with no sales call.

Request your free diagnostic

Carlos Alberto Cardona B., who will reply to youCarlos Alberto Cardona B. · SEO Specialist