---
title: "How to ship one h1, title, meta description and JSON-LD on Lovable"
slug: title-meta-schema-lovable
published: 2026-09-23T13:21:21.896256+00:00
updated: 2026-09-23T13:21:21.896256+00:00
author: "Asif Rahman"
author_url: https://masifrahman.com
category: "AI Readiness"
tags: check:C3, platform:lovable, Lovable, JSON-LD, structured data, AI readiness
description: "Lovable auto-generates title and meta description per page, but h1 and JSON-LD need the SEO & AI search review. The exact click path for all four C3 signals."
url: https://aiscan.site/blog/title-meta-schema-lovable
---

## Quick summary

| C3 signal | Where it lives on Lovable | How you fix it |
|---|---|---|
| Title + meta description | Generated per page while Lovable builds your app | Ask in the project chat, there is no settings field |
| Single h1 | Flagged by the **Content structure** check | Click **Try to fix**, or ask the agent directly |
| JSON-LD | Flagged by the **Structured data** check | Click **Try to fix**, or describe the schema you want |
| Whether any of this reaches AIScan or Google | Depends on your template (TanStack Start or React + Vite) | See the setup guide linked below |

**Check first, then read the rest of this guide.** Run `npx aiscan-cli yoursite.com`, or paste the URL at [AIScan](https://aiscan.site/). It grades C3, structured HTML made of one h1, a title tag, a meta description and JSON-LD, plus the rest of the content, discoverability, bot-access and capabilities checks in one pass, free and with no account.

## Lovable doesn't give you a metadata file. It gives you an auditor.

Every other platform in this series has a place where title, meta description and schema live: a PHP template, a `metadata` export, a settings panel. Lovable has none of those for a project you didn't build the head tags into yourself. According to Lovable's own publishing documentation, fetched 23 September 2026, "Lovable generates your site's metadata while it builds your app: the site title, meta description, and site icon." There is no file to open and no field to type into for that part.

What Lovable gives you instead is a checklist that reads your actual code and your deployed pages, called the **SEO & AI search review**. Open it from **More → SEO & AI search** in the project toolbar, then click **Scan project**. Four of its findings map straight onto C3, listed here as verified on docs.lovable.dev:

| SEO & AI search review finding | What it covers | Maps to C3 |
|---|---|---|
| Page basics | `lang` attribute, viewport configuration | Supporting signal |
| Metadata | Title and meta description per page | Title + description |
| Structured data | JSON-LD present, parseable, matching the page | JSON-LD |
| Content structure | Missing or generic h1, skipped heading levels | h1 |

Each failing row gets a **Try to fix** button that hands the specific fix to the agent, or you can click **Try to fix all** and send every open finding in one message. The review runs on unpublished projects too, so nothing here waits for a live domain.

In our own corpus of 501 scanned sites, re-measured 9 September 2026, 248 currently pass all four C3 signals at once, worth knowing before you assume a partial score is unusual.

## Set the title and description by asking, not by editing

There is a genuine trap here for anyone used to a settings page: the title and description are not global. Lovable's documentation states plainly that "metadata is set per page… Lovable generates a unique title and description for every page of your app based on its content," and that changing it means asking in the project chat, for example: *"Change my site title to 'Acme Task Tracker' and write a meta description about team to-do lists."* That request is treated as a normal build message and spends credits like any other edit, according to the same page.

| To check the result | Open this | What you see |
|---|---|---|
| While editing | The page selector above the preview | That page's **Social** and **Search** cards |
| From the Publish dialog | The **⋮** menu, or the favicon next to the URL | **Social & search appearance** |
| Right after publishing | The **Your website is live** screen | An **Edit** link next to the site's title |

A metadata change only reaches the live site on your next publish, exactly like a code edit. If the project is already published, Lovable's reply ends with a **Publish to update the live site** button, so you don't have to hunt for the Publish dialog separately.

## Let the review add the missing h1, then check what it actually wrote

The **Content structure** check fails on a missing h1, a heading that skips from h1 to h3, or an h1 so generic it says nothing about the page, in Lovable's own words: "H1 is missing or too generic" and "Heading levels skip from H1 to H3." Clicking **Try to fix** sends that finding to the agent, which edits the component that renders the page rather than a template file, because on a Lovable project there usually isn't a separate template to edit.

Read the diff before you accept it. An agent asked to add an h1 on a page that already has a large, unstyled heading sometimes wraps a second element instead of promoting the first one, which trades a missing-h1 finding for a two-heading finding on the next scan. Confirming the tag count after every fix, not just after the whole pass, catches that in one page load instead of a full review cycle.

## JSON-LD is a finding, not a code snippet you paste in

The **Structured data** check is stricter than "does a script tag carrying JSON-LD exist." Lovable's own documentation for the check names three separate failure modes, verified on docs.lovable.dev: JSON-LD that "cannot be parsed," JSON-LD that "does not match the visible page," and a page that "clearly qualifies for a supported Google Search feature and already shows the facts that feature needs, but carries no markup for it." It's also explicit about what does not count as a problem: a missing generic `WebSite` or `Organization` block, and a missing `FAQPage` markup, are both called out as non-issues on their own.

**Try to fix** here either adds a new JSON-LD block matched to the page's actual content, a product page gets `Product`, an article gets `Article`, or repairs an existing block so its fields match what's on the page. If you'd rather brief the agent yourself, describe the entity and the fields you want rather than pasting a generic schema.org example. A copied `Organization` snippet with placeholder values is exactly the "does not match the visible page" failure the check is built to catch.

## Read the review panel and the rendered HTML. They can disagree.

A **Scanning your project…** header means results are stale; wait for it to finish before trusting a green check. After a **Try to fix** pass completes, the review marks that finding **Fixed** provisionally and only confirms it on the next scan, so run **Scan again** rather than taking the badge at face value.

Then check the deployed page itself, because Lovable's review and a crawler don't always see the same HTML:

```bash
URL=https://yoursite.com/some-page
curl -s "$URL" | grep -c '<h1' # expect 1
curl -s "$URL" | grep -o 'application/ld+json' | wc -l # expect 1 or more
curl -sI "$URL" | grep -i x-robots-tag  # a "noindex" here means you tested a preview host
```

If the curl output looks right but AIScan still reports a failure, the gap is almost always the template split covered in our full Lovable setup guide: an older React + Vite project only serves its pre-rendered HTML to crawlers Lovable has verified, and AIScan isn't on that list.

## Where AIScan fits, and where it doesn't

AIScan reads the HTML your server actually hands back, the same bytes an unverified crawler gets. On a React + Vite Lovable project that can be the single-page shell, by design, so a failing C3 there means an unverified client sees nothing yet, not that your h1 doesn't exist. On TanStack Start, AIScan sees exactly what everyone else does.

Lovable's own review goes further than our check in one specific way: it looks at whether your JSON-LD's `@type` genuinely matches the page, and whether a passing structured-data result even applies to that page's purpose. AIScan's C3 currently only asserts that a JSON-LD block is present and parses; it doesn't check the type against the content. Treat a Lovable "Structured data" pass as the stronger signal when the two disagree, and treat an AIScan pass as the one that also confirms an outside crawler can read it at all.

If your Lovable app pulls its articles from a connected WordPress or Shopify source rather than rendering them itself, this guide doesn't reach that content. A headless WordPress blog still needs its own robots.txt, schema and llms.txt handled on that domain, which is what [ThinkRank](https://thinkrank.ai) is built for, and a connected Shopify catalog needs the same from [StoreSEO](https://storeseo.com/).

## Ship it, then scan the domain that matters

Run the SEO & AI search review, click through **Try to fix all**, publish, then scan your published custom domain, not the `.lovable.app` preview, at [AIScan](https://aiscan.site/) and read C3 alongside E3, D1, D2, B2 and C2. The [full Lovable setup guide](https://aiscan.site/blog/ai-readiness-setup-lovable) covers the rendering split and the discoverability files this post doesn't. If your stack owns metadata a different way, the [Next.js](https://aiscan.site/blog/title-meta-schema-nextjs) and [Webflow](https://aiscan.site/blog/title-meta-schema-webflow) versions of this guide show two more mechanisms for the same four signals. Every platform guide lives at [aiscan.site/guides](https://aiscan.site/guides), and the check definitions for this dimension are at [/docs/checks/content](https://aiscan.site/docs/checks/content).

