Skip to content
back to journal

lovable

SEO for Lovable Apps: the Real Options in 2026

Lovable apps don't rank by default — they're SPAs. Here are the four real SEO options for Lovable: prerender, edge SSR, Next.js migration, or static export.

Ralph Duin · 8 min read
XLI
SEO for Lovable Apps: the Real Options in 2026

Lovable ships apps fast. It does not ship SEO. If you launched a product on Lovable and expected Google to find it, you already know the rankings do not arrive on their own. This post covers the real options for getting a Lovable app to rank in 2026, with working code you can drop in this week.

I run inspiredbyfrustration.com on the same stack Lovable generates (Vite + React SPA) and I ship the bot-visible HTML layer as an open-source Cloudflare Worker. Every recommendation here is something I run in production.

Lovable SEO means making a Vite+React single-page app readable to Googlebot and AI crawlers, which by default receive only an empty div where your content should be.

Why Lovable apps don't rank by default

Lovable generates a client-rendered React SPA. That means three structural problems for SEO.

1. Googlebot sees the shell, not your content

Fetch a Lovable-built page with curl or as Googlebot and you get essentially this:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My App</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

Google does eventually render JavaScript in a second pass, but it is queued, rate-limited, and skips AJAX calls that look expensive. Perplexity, ChatGPT's browser, ClaudeBot and most AI crawlers do not render JS at all. They see an empty div and move on.

2. Core Web Vitals are structurally bad

The LCP element (your hero image, headline, or first card) lives inside a lazy-loaded chunk that fetches data from Supabase before paint. Mobile LCP on a fresh Lovable app routinely lands at 4 to 6 seconds. Google's threshold is 2.5.

3. No canonical, hreflang, or structured data

Lovable does not inject per-route <link rel="canonical">, does not generate JSON-LD, does not build a sitemap, and does not produce a robots.txt beyond the Vite default. You get none of the [technical SEO scaffolding](/technical-seo) a 2026 site needs.

The good news is each of these is fixable. There are three realistic options.

Option 1: Edge worker with bot detection and prerendered HTML

This is what I run on this site and what I recommend for 90% of Lovable apps. A Cloudflare Worker sits in front of your app. When a request arrives, the worker inspects the User-Agent. If it looks like a search engine or AI crawler, the worker fetches a prerendered HTML snapshot and rewrites the head with real title, meta, OG tags, canonical, and JSON-LD. Real users get the SPA untouched.

// worker.ts — simplified
const BOT_UA = /googlebot|bingbot|duckduckbot|yandex|baiduspider|slurp|applebot|petalbot|perplexitybot|chatgpt-user|gptbot|claudebot|oai-searchbot|anthropic-ai/i;

export default {
  async fetch(req: Request, env: Env): Promise<Response> {
    const ua = req.headers.get('user-agent') || '';
    const url = new URL(req.url);

    if (!BOT_UA.test(ua)) {
      return fetch(req); // real user, pass through to Lovable app
    }

    const snapshot = await env.SEO_KV.get(`snap:${url.pathname}`);
    if (!snapshot) return fetch(req);

    return new HTMLRewriter()
      .on('title', { element: (el) => el.setInnerContent(extractTitle(snapshot)) })
      .on('head', { element: (el) => el.append(extractMeta(snapshot), { html: true }) })
      .transform(new Response(snapshot, { headers: { 'content-type': 'text/html' } }));
  }
};

Pros: no Lovable code changes, runs at the edge in under 100ms, ships in a day, costs about $5/month on Cloudflare Workers Paid, and lets you own the SEO layer completely.

Cons: you maintain the worker and the snapshot pipeline. The bot-visible content must stay materially the same as the SPA content. Google's cloaking policy is about intent: prerendering your own site for crawlers is explicitly allowed; serving keyword-stuffed pages that do not exist in the SPA is not.

I describe the full pattern and publish the worker source on the technical SEO page. See also rescue your Lovable app if the site is already live and you need to retrofit SEO.

Option 2: AppHandoff to Next.js

The permanent fix: migrate off the SPA to Next.js App Router with React Server Components. Every page renders server-side on Vercel, the HTML that reaches Googlebot is the final HTML, and Core Web Vitals improve structurally.

Pros: real SSR, streaming, native metadata API, route-level OG image generation, and an ecosystem built around SEO. This is what I recommend for any Lovable app past product-market fit.

Cons: migration cost. Somebody has to port components, reroute data fetching to server components, move Supabase auth to server helpers, and handle the Vercel deploy. You then need ongoing Next.js expertise, which most Lovable-only teams do not have in-house.

I run this migration as a service. Full details and the migration playbook are in AppHandoff: Lovable to Next.js. If you are still deciding between stacks, Lovable vs Bolt vs Cursor covers the tradeoffs.

Option 3: Prerender.io or ReactSnap

Generic third-party solutions exist.

Prerender.io: hosted service. Put their middleware in front of your app, they render pages in a headless browser and cache. Works. Costs scale fast (roughly $90 to $500+/month depending on page count and refresh rate). You give up control of the snapshot layer and pay per render.

ReactSnap: build-time prerenderer. Generates static HTML for every known route at build time. Free, but only works for fully static content. No auth-aware rendering, no per-user data, no dynamic routes that depend on a database. Good for marketing pages, useless for the app itself.

Both are valid if you want to skip writing worker code. Neither gives you the cost or control of Option 1, and neither fixes the structural SSR problem like Option 2. If you want someone to implement the right option for your app, you can hire an AI developer who has done this on production Lovable codebases.

The non-negotiable list: what every Lovable app needs for SEO

Whichever option you pick, these items must be present on every route.

Per-route title and meta via an SEO component

// src/components/SEO.tsx
import { Helmet } from 'react-helmet-async';

export function SEO({ title, description, canonical, image }: Props) {
  return (
    <Helmet>
      <title>{title}</title>
      <meta name="description" content={description} />
      <link rel="canonical" href={canonical} />
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={image} />
      <meta name="twitter:card" content="summary_large_image" />
    </Helmet>
  );
}

Structured data per route

Inject JSON-LD for Person, Organization, BlogPosting, or Product as appropriate. Google uses this for rich results and AI Overview citations.

Sitemap.xml generated at build time

Write a Vite plugin or a post-build script that enumerates routes and writes public/sitemap.xml. Submit it in Google Search Console and Bing Webmaster Tools.

robots.txt with explicit AI directives

User-agent: Googlebot
Allow: /

User-agent: GPTBot Allow: /

User-agent: ClaudeBot Allow: /

User-agent: PerplexityBot Allow: /

User-agent: OAI-SearchBot Allow: /

Sitemap: https://yourdomain.com/sitemap.xml

Open Graph and Twitter Card images

Every indexable route needs a 1200x630 OG image. Generate them at build time with @vercel/og or satori.

Canonical on every page

Self-referencing canonical prevents duplicate indexing of query-string variants and trailing-slash versions.

Core Web Vitals for Lovable apps

SEO basics aside, the ranking ceiling on a slow SPA is low. Fix these four.

LCP: the largest element after hydration is usually the hero image or a headline inside a framer-motion wrapper. Preload the hero image with <link rel="preload" as="image" fetchpriority="high"> and replace framer-motion hero animations with plain CSS. I shipped exactly this fix on the IBF blog (see the b8dfed0 commit) and cut mobile LCP from 4.1s to 1.8s.

FCP: inline critical CSS. Use the Critters plugin or the Vite critical plugin. The first paint should not wait on a stylesheet fetch.

CLS: put explicit width and height on every image and reserve space for lazy-loaded sections. Lovable's default components rarely include these.

TBT and INP: defer non-critical JavaScript. Wrap analytics and chat widgets in requestIdleCallback. Use React.lazy for below-the-fold routes.

Measuring: PSI, GSC, and DataForSEO

Shipping SEO without measurement is guessing. Run these three loops.

Weekly PageSpeed Insights mobile run. I script it with bun run psi:mobile against every key route and dump the results into a CSV. Track LCP, CLS, INP, and the overall score week over week. Regressions get a Linear ticket.

Google Search Console. Submit the sitemap, watch the Coverage report for indexing errors, and use URL Inspection on any new route. GSC tells you exactly which pages Google rendered and which it gave up on.

DataForSEO weekly rank tracking. A Python cron hits the DataForSEO SERP API every Monday for the 30 to 50 keywords that matter, stores positions in Postgres, and emails a diff. Costs about $2/month for a small keyword set and beats manually checking rankings in an incognito window.

FAQ

Can Lovable apps rank in Google?

Yes, with work. Out of the box, no. Once you add a prerender layer, per-route meta, structured data, and fix Core Web Vitals, Lovable apps rank the same as any other React site. I rank on page one for multiple lovable expert queries from a Lovable-style SPA.

Does Lovable support SSR natively?

No, as of mid-2026. Lovable generates Vite + React client-rendered apps. There is no server-render mode in the product. If you need SSR, you either add an edge prerender layer or migrate.

What about AI crawlers? Which user agents should I allow?

The ones worth serving in 2026: GPTBot, OAI-SearchBot, ChatGPT-User (OpenAI), ClaudeBot, anthropic-ai (Anthropic), PerplexityBot, Google-Extended (Gemini training and AI Overviews), Applebot-Extended, and Bingbot (also powers Copilot). Your edge worker's bot detection regex should match all of these.

Is serving different HTML to bots vs users considered cloaking?

Google's policy is about intent. Serving a prerendered snapshot of the same content your users see is explicitly allowed and is how most JS-heavy sites rank. Serving a crawler a page full of keywords that does not exist in the real app is cloaking and gets you deindexed. Keep the bot-visible content a faithful representation of the SPA content and you are fine.

Should I just migrate to Next.js?

Depends on stage. Pre-PMF, ship the edge worker and stay on Lovable. Post-PMF with real SEO ambition, migrate. The worker is cheap and reversible; a Next.js rewrite is a 2 to 6 week investment that only pays off when organic traffic is a growth lever.

If you want me to ship the edge worker for you, or scope a Lovable to Next.js migration, get in touch. If you are not sure which option is right for your stage, a fractional CTO review is the fastest way to get an architecture recommendation before committing budget. Everything on this site runs the stack this post describes.

Frequently asked questions

Can Lovable apps rank in Google?
Yes, with work. Out of the box, many Lovable apps are too client-rendered for serious SEO. Once you add crawlable HTML, per-route metadata, structured data, sitemap hygiene, redirects, and Core Web Vitals fixes - or migrate the growth pages to Next.js App Router - Lovable-originated apps can rank like any other React product.
Does Lovable support SSR natively?
No, as of mid-2026. Lovable generates Vite + React client-rendered apps with no native server-render mode. If SEO is a revenue channel, the durable path is usually moving high-value routes to Next.js App Router or another SSR-capable frontend.
What about AI crawlers? Which user agents should I allow?
The ones worth allowing in 2026: GPTBot, OAI-SearchBot, ChatGPT-User (OpenAI); ClaudeBot, anthropic-ai (Anthropic); PerplexityBot; Google-Extended (Gemini + AI Overviews); Applebot-Extended; and Bingbot (also powers Copilot). Keep robots.txt, CSP, caching, and server-rendered metadata aligned so crawlers see the same crawlable content users see.
Is serving different HTML to bots vs users considered cloaking?
Google's policy is about intent. Serving a prerendered snapshot of the same content your users see is explicitly allowed and is how most JS-heavy sites rank. Serving bots content that does not exist in the real app is cloaking. Keep the bot-visible content a faithful shadow of what users render.
Should I just migrate to Next.js?
Depends on stage. Pre-PMF, fix metadata, redirects, and crawl blockers first. Post-PMF with real SEO ambition, migrate the indexable marketing and content routes to Next.js App Router: it is a 2–6 week investment that pays off when organic traffic is a growth lever.
▢ end of post
XLinkedIn