All posts

On-page

Fix the Lovable "Vite + React" title tag bug in 5 minutes

Every page on your Lovable site is titled "Vite + React". Google indexes them as duplicates and ranks none of them. Here's how to give every page a unique title.

·4 min read

The bug

Open any Lovable project, deploy it, then open every page in a separate tab. Look at the browser tab titles. They almost certainly all read "Vite + React", or your project name, on every single page.

That's the title tag — and it's the single most important on-page ranking signal Google uses. When every page has the same title, Google treats them as duplicates and ranks none of them well.

Why it happens

Lovable's TanStack Start template defines title in the root route's head(). Child routes inherit it unless they override it. Most generated routes never set their own title, so the root one wins on every page.

The fix (per-route head)

In every route file, add a head option that returns the page's own title and meta description:

// src/routes/pricing.tsx
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/pricing")({
  component: PricingPage,
  head: () => ({
    meta: [
      { title: "Pricing — Acme | Invoicing for freelancers" },
      { name: "description",
        content: "Simple per-invoice pricing. No subscriptions. UK & EU VAT handled." },
      { property: "og:title", content: "Acme pricing" },
      { property: "og:description",
        content: "Simple per-invoice pricing. No subscriptions." },
    ],
  }),
});

Do this for every route file in src/routes/. It takes about 30 seconds per page.

Title formula that ranks

For most B2B and SaaS pages this format wins:

Primary Keyword — Benefit | Brand

Examples: "Free invoice generator — UK VAT included | Acme" / "Lovable SEO audit — free 14-point report | RankLovable".

Keep it 50–60 characters. Google truncates anything longer in search results.

Don't forget dynamic routes

For dynamic routes (blog posts, products, profiles), build the title from loader data:

export const Route = createFileRoute("/blog/$slug")({
  loader: ({ params }) => fetchPost(params.slug),
  head: ({ loaderData }) => ({
    meta: [
      { title: `${loaderData.title} | Acme Blog` },
      { name: "description", content: loaderData.excerpt },
    ],
  }),
});

How to verify it worked

Re-deploy. Open every page. The browser tab title should change. Then run your sitemap through Screaming Frog (free up to 500 URLs) and confirm every URL has a unique title.

Of all the SEO fixes for AI-built sites, this single change moves the needle fastest. We've seen Lovable sites jump from page 4 to page 1 inside a week off this fix alone.

Don't want to fix it yourself?

Get the free 14-point audit.

We scan your site for the same issues this article describes — plus 13 more — and send you the full report. No signup needed.

Run free audit