lovable
Your Lovable app isn't on Google? Five root causes, ranked. SPA rendering, missing per-route metadata, sitemap gaps, cache config, and how to fix each one.
Your Lovable app isn't showing up on Google. You shipped it, you can see it at your-domain.com, you can site:your-domain.com Google and find approximately nothing. The page isn't broken — it's invisible to crawlers. This is the most common Lovable production-readiness gap, and it's almost always one of five root causes. Here's how to diagnose, then fix it.
The summary up front: Lovable generates a Vite + React SPA. SPAs ship an empty <div id="root"> to crawlers and rely on JavaScript to build the page. Google can technically render JS, but the rendering is delayed, the queue is deep, and a brand-new low-authority site can wait weeks for the second pass. Bing and most AI crawlers don't render JS at all. If you want to rank, you have to make the HTML the crawler sees match the page a user sees — and that means one of a small number of well-defined fixes.
Open a terminal and run, against your live site:
curl -sL -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://your-domain.com/ | head -c 2000
What do you see in the first 2 KB of HTML?
<div id="root"> and a <script src="/assets/index-...js"> tag, no title or meta tags filled in → cause is #1 below (no SSR, no prerender).<title> tag that says "Lovable App" or your old project name, the same on every URL → #2 (no per-route metadata).<title> and meta but it's all the same across /, /pricing, /blog → #3 (one-size-fits-all metadata)./ but 404 / 403 on /sitemap.xml or /robots.txt → #4 (no discovery surface).no-store, private, or CDN says cf-cache-status: BYPASS → #5 (cache config blocking crawlers).Then go fix that one.
This is the most common cause. The exported Lovable codebase is index.html + a Vite bundle. The HTML body is approximately empty until JavaScript runs. Googlebot can render JS, but:
window, document, or any browser-only API at module scope during render, the Googlebot render fails silently and the page is dropped.The fix is one of four, in increasing order of effort and reward:
For more on which of these to pick, see SEO for Lovable Apps.
<title> and <meta> aren't being setIn a React SPA, the per-route title is usually set client-side via react-helmet, react-helmet-async, or a custom hook. Crawlers that don't run JS see whatever was in the initial HTML's <head> — typically the project default ("Lovable App", "Vite + React + TS"). Every URL has the same title.
The fix: whichever rendering path you pick (prerender / static export / Next.js migration), make sure the per-route metadata is in the server-rendered HTML, not just the client-side helmet. In Next.js this is automatic via the metadata export in each page.tsx. In a prerendered SPA, it's the prerender tool's job — verify the prerendered output actually has the per-route titles set.
Sometimes the per-route metadata wiring exists but every route is using the same global default. Symptom: view-source: on /, /about, /pricing all show identical <title> and <meta name="description">.
The fix: each route needs unique metadata. In a Lovable codebase that's typically:
// src/pages/Pricing.tsx
import { useEffect } from "react";
export default function Pricing() {
useEffect(() => {
document.title = "Pricing — YourBrand";
// and update meta description, og:title, etc.
}, []);
// ...
}
If you're prerendering, that useEffect runs during prerender and the HTML output captures the updated title. If you're not prerendering, the useEffect runs in the user's browser after the crawler already left — so the crawler sees the default. Cause 3 collapses back into Cause 1 (need server-rendered HTML).
If you've migrated to Next.js, each route exports its own metadata object — done. See the Lovable.dev to Next.js migration prompts for the exact refactor.
sitemap.xml, no robots.txt, no discovery surfaceCrawlers find your URLs primarily through links from other pages and through your sitemap.xml. New low-authority sites have almost no inbound links, so the sitemap is the discovery surface.
The fix:
sitemap.xml. In Next.js: app/sitemap.ts with the routes from your data layer. In a prerendered Vite SPA: a build-time script that lists all known routes. Submit it in Google Search Console (Sitemaps section) and Bing Webmaster Tools.robots.txt. Even a one-liner pointing at the sitemap helps:
User-agent: *
Allow: /
Sitemap: https://your-domain.com/sitemap.xml
Disallow: /. I've seen Lovable projects deploy with a placeholder robots.txt that blocks the entire site. Five-second check, ten-day index drop.curl -sL https://your-domain.com/sitemap.xml should return well-formed XML with <loc> entries. Empty or 404 = your discovery surface doesn't exist.Less common but ugly when it happens. Your Cloudflare config, your origin headers, or a custom Worker is serving different content to bots vs humans — sometimes accidentally.
Symptoms and fixes:
cache-control: no-store on HTML: prevents edge caching, slows crawl rate, and on poor cache layers can starve crawlers entirely. Fix: use s-maxage=3600, stale-while-revalidate=86400 for HTML; reserve no-store for genuinely private routes.cf-cache-status: BYPASS everywhere: Cloudflare is bypassing cache; usually because your origin sends cache-control: private. Fix: make the origin send proper public cache headers, then cf-cache-status should become HIT over time.PerplexityBot, ChatGPT-User, ClaudeBot, Google-Extended) explicitly.Strict-Transport-Security: max-age=31536000; includeSubDomains; preload on every HTTPS response.The temptation when nothing ranks is to do everything at once. Don't. Each fix takes a different time to show up in Google. Do them in this order:
robots.txt exists, sitemap.xml exists, both return 200, sitemap has real URLs. Effect: hours to days.If you skip step 2, every other step is performative. The crawler still sees an empty HTML body.
Patching (prerender + sitemap + metadata fixes) is right when:
Migrating to Next.js is right when:
Most teams patch first, then migrate when the patch's edges start to fray. That's a reasonable path. See the Lovable to Next.js migration service when you're ready.
For a low-authority site that just fixed the rendering problem: 2–6 weeks for Google to recrawl, re-render, and update the index. New URLs without inbound links may take longer — submit them via GSC URL Inspection's "Request Indexing" button to accelerate.
It can crawl the HTML, yes. Whether it sees your actual content depends on whether you ship server-rendered HTML (yes) or client-rendered JS (maybe, slowly, sometimes never). The curl -A "Googlebot/2.1" test above is the truth.
Not natively. The output is Vite + React Router. To get SSR you migrate to a framework that ships it: Next.js, Astro, or Remix. See Lovable alternatives for the comparison.
<meta> tags via react-helmet fix my rankings?Only for the slice of crawlers that render JavaScript. Bing, most AI crawlers, and the "first pass" of Googlebot don't. If your content needs to rank on Bing or be cited by AI assistants, the metadata needs to be in the server-rendered HTML.
Prerender is enough for the SEO problem. It's not enough for the broader production-readiness problem (monorepo, multi-env, CI gates, observability, the team-handoff story). Pick patching when SEO is the only blocker. Pick migration when SEO is one of several blockers.
— Inspired By Frustration
// keep reading
lovable · 9 min
Lovable vs Replit in 2026: output quality, pricing, use-case fits, and which one ships production faster. Honest take from shipping with both.
lovable · 8 min
A production guide for porting Lovable-built app slices into a Next.js monorepo with SSR safety, schema contracts, and SEO guardrails.