Do Lovable websites rank on Google? The problem and the fix

    Yes, a Lovable site can rank perfectly well — but not by default. A single-page application serves the same HTML file on every URL and injects the content afterwards, in JavaScript. Without pre-rendering, Google crawls little, and AI engine bots, which do not run JavaScript, see nothing at all.

    Published Updated

    Why does a Lovable site start with a handicap?

    The handicap has nothing to do with Lovable specifically: it affects every single-page application, whether hand-written in React, generated by another tool, or produced by an AI. Client-side rendering is the default mode of the modern application web, and it is excellent for user experience — but it puts crawlers in a very different position from a browser.

    Understanding exactly what a bot receives is the first step. As long as you reason from what you see on screen, everything looks fine: titles are correct, pages are distinct, links work. The problem only exists in the raw HTTP response, which nobody ever looks at.

    What does a single-page application change for Google?

    A single-page application has one HTML document. The server returns that same file for the home page, the contact page, a blog post or a product page. The file only contains a shell: a handful of meta tags, an empty container and a reference to a JavaScript bundle. Once the JavaScript runs in the browser, the router reads the URL and replaces the container's content with the right page.

    For Google, this means deferred rendering. Crawling happens in two stages: the bot downloads the HTML, sees it is empty, then queues the URL so that a headless browser can execute the JavaScript later. That second pass is neither immediate nor guaranteed at the same pace as the first, and it is expensive on the search engine's side.

    On top of that comes a subtler effect: crawl budget. A bot has a limited request volume per site, calibrated on domain authority. When every URL returns an identical document, the engine gets no novelty signal and no reason to dig further. On a recent domain the typical outcome is not rejection: it is a plain absence of crawling.

    Why do AI engines see nothing at all?

    This is the point almost nobody explains, and it is the sharpest one. Answer-engine bots — GPTBot, ClaudeBot, PerplexityBot, CCBot and most of the collectors that feed language models — are plain HTTP clients. They request a URL, read the returned HTML and stop there. They ship no rendering engine and do not execute JavaScript.

    On a single-page application without pre-rendering, these bots therefore receive an empty shell. Not thin content: nothing. Not one sentence from the page, no specific title, no table, no data. A company can have published fifty pages of solid content and remain entirely absent from these engines' answers, because from the collector's point of view that content never existed.

    The contrast with Google is stark. Google usually renders the page eventually, late. AI engines get no second chance: whatever was missing from the first HTTP response never enters their corpus. As a growing share of searches moves to conversational interfaces, that silence costs more than a poor ranking.

    How can you check your own site in thirty seconds?

    The test takes two commands. Request two different URLs from the site while identifying as a bot, then compare what comes back. Open a terminal and run:

    curl -s -A "GPTBot/1.0" https://your-domain.com/ | wc -c

    curl -s -A "GPTBot/1.0" https://your-domain.com/another-page | wc -c

    First compare the two byte counts. If they are strictly identical, both URLs serve the same file: the site is not pre-rendered. Then compare the title actually sent, using grep -o "<title>[^<]*" on each response. If both pages announce the home-page title, the diagnosis is confirmed.

    A third check makes the demonstration final: request a URL that does not exist, such as /made-up-page-123. If it also answers with the same document and a 200 status, the site is serving an unlimited number of indexable copies of its home page. On a pre-rendered site, by contrast, each URL returns a different byte count and a different title, and the unknown URL is treated as an error.

    What are the three ways to fix it, and what do they cost?

    There are only three families of solutions, and they differ less in visible outcome than in the dependency they create. All three give the bot filled-in HTML; what changes is who produces that HTML, when, and whom you must keep paying for it to keep working.

    Build-time pre-rendering generates one complete HTML file per URL at compile time. Server-side rendering produces that HTML on every request, on an application server you have to maintain. A third-party pre-rendering service inserts a middleman that detects bots, renders pages for them and bills monthly — market offers commonly range from $15 to $99 per month depending on page volume, a legitimate price for a managed service, but a permanent external dependency nonetheless.

    Three ways to make a single-page site readable by bots
    ApproachWhat a crawler receivesEffect on AI crawlersRecurring costDependency
    Build-time pre-renderingOne complete, distinct HTML file per URL, generated at compile timeFully readable content from the first HTTP responseNone (build time only)None: the files belong to the client
    Server-side rendering (SSR)Complete HTML generated on every requestFully readable content from the first HTTP responseHosting an application server you must maintainRuntime platform and continuous monitoring
    Third-party pre-rendering serviceHTML rendered by a middleman that detects the botReadable as long as the subscription is active and the bot recognisedCommonly $15 to $99 per month depending on page volumeExternal vendor in the critical path
    Price range taken from the public pricing pages of on-demand pre-rendering services, accessed in July 2026. No vendor is targeted: these services answer a real need, particularly when the source code cannot be modified.

    Why do we pre-render at build time?

    Because the result is a folder of HTML files the client owns. At the end of the build, every public URL exists as a standalone file with its title, description, canonical tag, hreflang tags, JSON-LD and full text. Those files can be served from any static host, including one that is not ours.

    So there is no subscription to renew, no middleman to query when a bot complains, and no application server to watch overnight. If the agency disappeared, the site would remain readable by search engines exactly as on delivery day. It is the same logic as the one described in our delivery methodology: what is delivered must remain usable without us.

    Build-time pre-rendering has one honest trade-off: you must recompile to publish a content change. On a marketing site, a resource library or an editorial blog, that constraint is negligible. On an application whose public content changes several times an hour, server-side rendering becomes the right answer again — and we say so before the quote, not after.

    What did we measure on our own site?

    This site had exactly the problem described above. We document it because that is where a page like this gets its credibility: we did not read it somewhere, we observed it on our own domain and then fixed it. Every figure below was measured on 31 July 2026, before and after pre-rendering was put in place.

    Before the fix, the 83 URLs declared in the sitemap served a strictly identical HTML file: same md5 fingerprint, 75,482 bytes, including on a URL that did not exist. The site carried no canonical tag at all, and every URL announced the home-page title.

    After the fix, the site serves 91 URLs matching 91 distinct HTML files, 91 unique titles and 91 unique descriptions. The canonical tag is self-referencing on 91 URLs out of 91, hreflang is present on 91 out of 91, and each page carries its own JSON-LD. The median amount of genuinely pre-rendered text is 9,783 characters per page, ranging from 945 characters at the low end to 50,615 at the high end.

    Before / after pre-rendering — measured on lovablewebagency.com on 31 July 2026
    MetricBeforeAfter
    URLs declared in the sitemap8391
    Distinct HTML files served1 (same md5 fingerprint, 75,482 bytes)91
    Unique titles0 — home-page title everywhere91
    Unique descriptions091
    Self-referencing canonical tag0 across the whole site91 / 91
    Reciprocal hreflangAbsent91 / 91
    Per-page JSON-LDOne shared graphA graph specific to each page
    Pre-rendered text per page (median)0 characters9,783 characters (945 min — 50,615 max)
    Non-existent URL200 with the home-page HTMLTreated as an error, set to noindex
    Scope: our own domain, lovablewebagency.com. No client data is used on this page.

    What did Search Console say at the time of the fix?

    The indexing report showed 8 indexed pages and 78 non-indexed pages. Of those 78, 76 were classified as "Discovered - currently not indexed", with "Last crawled: N/A". In other words, Google knew about these URLs from the sitemap but had never crawled a single one of them.

    The decisive figure is the other one: zero pages under "Crawled - currently not indexed". That category holds pages Google downloaded and then set aside, usually for insufficient quality or duplication. It was empty. Google had therefore passed no judgement on the content: it had simply never looked.

    This is an important operational distinction. A site rejected after crawling has a content problem, and rewriting the pages is the right answer. A site that was never crawled has an access problem, and no amount of extra content solves it while every URL serves the same file. We were in the second case, and the technical fix had to come first.

    What mistakes should you avoid?

    Three mistakes come up systematically when trying to fix a single-page application's SEO in a hurry. The first two can make things worse than the original problem; the third wastes weeks chasing an invisible cause.

    Why should you never inject hidden text for bots?

    The temptation is strong: since the bot cannot see the content, you add a block of text into the document meant only for it, hidden from users by CSS or pushed off-screen. That practice has a name in Google's spam policies: hidden text. It is explicitly forbidden, just like showing different content to bots and to visitors.

    The possible penalty is not a mere algorithmic adjustment but a manual action — a human decision targeting the site, with a reconsideration process to follow. The cost-benefit ratio is disastrous: you gamble the domain's entire visibility for content that pre-rendering would have made visible legitimately.

    We deliberately describe no method for doing it. The useful rule is simple: what is sent to the bot must be exactly what the user sees. Pre-rendering respects that rule by construction, since it produces the HTML of the real page.

    What is a soft 404 and how do you fix it?

    Static hosting generally returns the index.html file for any URL it does not know. On a single-page application, that means a made-up address answers with HTTP 200 carrying the home page's content, canonical tag and indexing directive. Every typo in an external link, every stale URL, every randomly generated address thus becomes an indexable copy of the site.

    The fix belongs to the router, at the moment the application finds no matching route. Three moves are enough: replace the robots directive with noindex, nofollow; remove the canonical tag inherited from the static document, so the URL is not attributed to the home page; and replace the title with a real error title in the language of the requested URL.

    One detail matters: the requested URL must stay in the address bar. Silently redirecting to the home page reproduces the problem in another form, since the engine then records a redirect from an address that should never have existed.

    Why does deleting a file not remove it from the web?

    An obsolete sitemap, an old robots.txt or an orphaned page deleted from the repository often keeps being served in production. The reason is mechanical: a static deployment publishes the files present in the output folder, but does not necessarily erase those that were there before, and the delivery network's cache keeps the previous version for as long as it remains valid.

    In practice, you can spend a day fixing a sitemap in the code without a single correction showing up online, because the old file is still being served. The right reflex is to verify each fix directly against the public URL, with curl, rather than in the repository.

    When a file must disappear, overwrite it with valid empty content or replace it with a redirect rather than deleting it and hoping. Then always check what the address actually returns in production.

    Where do you start on a Lovable site that is already live?

    The order of operations matters more than the volume of work. Start with the two-command curl diagnosis described above, to establish that the problem really is an access problem. Then put pre-rendering in place, producing one file per public URL. Fix the behaviour of unknown URLs to remove soft 404s. Finally, verify that every served page carries a title, a description, a self-referencing canonical and its hreflang tags — by querying the public URL, not the code.

    Only after these four steps does producing more content make sense: while pages are not being crawled, adding more only lengthens a list nobody reads. This is also the moment to check that the sitemap declares only URLs that are actually served, and that robots.txt allows answer-engine collectors.

    For a project still being designed, the reasoning is identical but the effort is far smaller: pre-rendering is decided during scoping, alongside URL architecture and the content plan. That is what we detail on our page about using Lovable for a production SaaS.

    Key data

    83 of 83, 75,482 bytes
    URLs serving identical HTML (before)
    Observed on our projects
    91 of 91
    Distinct HTML files (after)
    Observed on our projects
    91 / 91
    Self-referencing canonical (after)
    Observed on our projects
    9,783 characters
    Pre-rendered text per page (median)
    Observed on our projects
    8 indexed, 78 not indexed, of which 76 "Discovered - currently not indexed"
    Search Console at the time of the fix
    Observed on our projects
    0
    Pages "Crawled - currently not indexed"
    Observed on our projects

    Related questions

    Does Google execute JavaScript?
    Yes, but in two stages: the HTML is downloaded first, then the URL is queued for later rendering. That second pass is deferred and expensive, and nothing guarantees it happens for every URL on a recent domain.
    Do AI engine bots execute JavaScript?
    No. GPTBot, ClaudeBot, PerplexityBot and CCBot read the raw HTML response. Without pre-rendering they receive an empty shell, and the page content never enters their corpus.
    How long before you see an effect?
    It depends on the domain's own crawl rate, which nobody controls. What is immediately verifiable is the HTML being served: from the moment it goes live, every URL returns its own content — and that is the check that means something. No indexing timeline can be promised.
    Do you have to leave Lovable to rank?
    No. The behaviour described applies to any single-page application, whatever tool produced it. Since the generated code is standard React exported to GitHub, a pre-rendering script can be added at build time without changing platform.
    Does pre-rendering slow the site down?
    No — it speeds up first paint: the browser receives already-filled HTML and does not wait for JavaScript to display text. The cost lies solely in build duration, which grows with the number of URLs.
    What should you do with a Lovable site already live and not indexed?
    In order: run the two curl commands, put pre-rendering in place, fix unknown URLs so they return noindex with no inherited canonical, then verify title, description, canonical and hreflang directly against the public URLs. Extra content comes after that, not before.

    Keep exploring the site

    Sources & external links

    About the author

    Simon Berna
    Founder of Lovable Web Agency

    Simon Berna is president of Axe Capital and founder of Lovable Web Agency. He helps entrepreneurs and SMEs design, ship and scale websites and apps built with Lovable AI.

    LinkedIn profile

    How we verify: pricing and features of the platforms mentioned come from their official pages, consulted on the update date above and linked at the end of this article. Durations, iteration counts and project costs labelled "observed on our projects" come from engagements delivered by Lovable Web Agency, with their scope stated. We publish no unsourced projection or market average, and we correct a figure as soon as a vendor changes its pricing.

    Publisher: Axe Capital, a French SAS registered in Lyon, SIREN 904 636 222, operating the Lovable Web Agency brand.

    Updated

    Want to go further on your project?

    Ready to launch your
    web project?

    Let's discuss your project and choose the package that suits you

    Response within 24 hours
    No commitment
    Personalized quote
    fr