Fix AI visibility / Lovable

Why AI crawlers can't read your Lovable site

Lovable server-renders new projects by default and serves older client-rendered projects a rendered copy to recognized crawlers, so many sites are readable. The gap is browser-fetched content and any crawler Lovable does not recognize.

The honest answer depends on when your project was built and how it loads content. Since May 13, 2026, new Lovable projects are server-rendered by default on TanStack Start, and their static routes are pre-rendered to plain HTML, so a lot of published Lovable pages are already readable by crawlers that do not run JavaScript. Older client-rendered projects are not simply invisible either. When Lovable hosts them, it renders the page server-side for verified crawlers and serves that HTML. Both are real improvements over the old default.

The gap that remains is specific, not universal. Most AI crawlers, including GPTBot, ClaudeBot, and PerplexityBot, fetch your raw HTML and do not execute JavaScript, and Lovable's rendered copy only reaches crawlers it recognizes and serves. So any crawler Lovable does not serve, any route you leave client-rendered, and any data your app fetches in the browser after load can still arrive as an empty shell. The reliable move is to confirm what your published URL actually returns, then move the content that matters into server-rendered or pre-rendered output rather than relying on a fetch that runs in the browser.

How Lovable renders

Before May 13, 2026, Lovable generated React and Vite single-page apps that were purely client-side rendered and deployed as static files, so the first response a crawler received was a near-empty shell, essentially a div with id root and a script tag, with the visible content built only after JavaScript ran in the browser. That is the classic empty-shell case for the many AI crawlers that fetch raw HTML and do not execute JavaScript. Two things changed that picture. First, projects created on or after May 13, 2026 default to TanStack Start with per-route rendering: static routes such as landing, marketing, and blog pages are pre-rendered to flat HTML at deploy time, and server-rendered routes run the React tree and its loaders on the server and stream fully-formed HTML, so their content is present in the raw response to every client. Second, for older client-rendered projects hosted on Lovable, Lovable now does dynamic rendering: when a verified crawler requests a page, Lovable renders it server-side in a headless browser and serves that HTML, so a recognized crawler can receive real content even though the same URL still returns a shell to an ordinary browser. Content stays invisible to a no-JavaScript fetch in three situations that survive the change: older client-rendered projects when the fetcher is not a crawler Lovable recognizes and serves rendered HTML to, individual routes you leave as client-side rendering, and any data your app fetches in the browser after load rather than in a server loader, since only what the server produced at request or deploy time is in the HTML. Exporting the code and serving a plain static build without an SSR runtime also reverts to the empty shell.

The fix

  1. Check what your published URL actually returns

    Open your live page, then view the page source (right-click, View Page Source) or fetch it without JavaScript, and look at the HTML before any script runs. If your headline and body text are present, crawlers can read them. If all you see is a div with id root and a bundle of script tags, the content is being built client-side and a no-JavaScript fetch gets nothing. Note that Lovable can serve a rendered copy to crawlers it recognizes, so a recognized crawler may receive more than your browser does. Testing with a crawler user-agent, not just the browser, tells you what each one actually gets.

  2. Confirm whether you are on the current server-rendered stack

    Projects created on or after May 13, 2026 default to TanStack Start and server-render or pre-render their routes, so their content is in the HTML for every client. Projects created before that date still ship as client-rendered single-page apps, and Lovable now covers them with dynamic rendering: it renders the page in a headless browser and serves that HTML to verified crawlers. That helps, but it keys on the crawler being recognized and does not change what browser-fetched data returns. If you want content in the HTML for every client regardless, recreating the page on the current stack, or moving its content onto server-rendered routes, is the durable fix.

  3. Fetch data in server loaders, not in the browser

    Even on the server-rendered stack, only what the server produces at request or deploy time lands in the HTML. Content you load client-side, for example a browser-side Supabase or API call inside a useEffect, is absent from the raw response and reaches a no-JavaScript fetch as blank. Move data your page depends on into route loaders or server functions so it is rendered into the HTML the server sends, and keep SEO-critical routes on SSR or SSG rather than per-route client-side rendering.

  4. If you export the code, keep an SSR runtime

    Content is server-rendered when Lovable hosts and runs it, or when you deploy it to a host that runs the SSR server. If you export the project and serve a plain static build of the single-page app without that runtime, you are back to shipping an empty shell, and Lovable's dynamic rendering for crawlers does not travel with the export. Either publish on Lovable's hosting, deploy to an SSR-capable host, or pre-render the routes to static HTML before serving them.

  5. Verify with a Lantad scan

    Run your published URL through Lantad. It fetches the page as LantadBot with no JavaScript, then renders it fully in a browser, and diffs the two. Prose Parity reports the share of the rendered, visible text that is present in the raw HTML: at 100 percent a fetch sees everything a visitor sees, and any gap is content that a crawler getting that same response never receives. Because Lovable can serve rendered HTML to crawlers it recognizes, Access checks the raw response per named crawler so you can see who is served real content and who is not, and Structure checks your semantic HTML. Being fetched and read is the prerequisite for being cited. It never guarantees a citation, but it is the part you control.

Common questions

I read that Lovable now does SSR. Doesn't that mean my site is fine?
Often, but check. New projects created on or after May 13, 2026 are server-rendered by default and many are readable, and older projects hosted on Lovable get a rendered copy served to verified crawlers. What is not covered is any crawler Lovable does not recognize, routes you leave client-rendered, and data your app fetches in the browser, which can still arrive as an empty shell. Confirm what your published URL returns rather than assuming.
Why does my Lovable page look complete in the browser but empty to ChatGPT?
Most AI crawlers, including GPTBot, ClaudeBot, and PerplexityBot, fetch the raw HTML your server returns and do not run JavaScript, while your browser runs the scripts that build the visible page. If your content is injected client-side and the crawler is not one Lovable serves a rendered copy to, it receives the shell the server sent. View the page source, or do a no-JavaScript fetch with the crawler user-agent, to see exactly what each one gets.
Will a robots.txt change make my content readable?
No. robots.txt controls whether a crawler is allowed to fetch a page, not whether the content is present in the HTML once it does. If your page ships as a client-rendered shell and the crawler is not served a rendered copy, allowing every crawler still leaves them with nothing to read. Rendering the content server-side is the fix, and robots.txt only governs permission.

See what AI reads on your Lovable site

Run a free scan: paste a URL and see exactly what AI crawlers can and cannot read, with a graded report and ranked fixes.