<!-- Built by scripts/build-agent-docs.mjs from site/agents-src/seo.md: edit that file. -->
# Page Lemon search and AI search: guide for AI assistants

> For people: https://pagelemon.com/docs/seo explains this feature in plain words. This page is for AI assistants.

Getting a Page Lemon site found in Google and Bing, on maps, and in AI answers (ChatGPT, Claude, Perplexity, Google AI Overviews). Page Lemon does the plumbing on its own, on every plan: the 7-day wait for new free sites, one main address (a canonical `Link` header on the other addresses, and same-site canonicals in pages corrected when served), `robots.txt`, `sitemap.xml` and `llms.txt` when the site has none, IndexNow pings after each publish, and `seo` hints in replies. For a local business the biggest levers are the person's own: a Google Business Profile and other listings, reviews, and one page per service. You write pages that people and search engines can read, and walk the person through the steps only they can do. Publishing in general: https://pagelemon.com/agents.

Use this when the person asks to be found ("Get my site on Google", "Why doesn't my site show up?", "Make my site show up when people search for a plumber in Bristol", "Can ChatGPT find my business?", "Stop AI companies training on my site", "Add this Search Console tag"), whenever you build or launch a site meant for the public, and when a deploy reply carries `seo` hints.

## Plans and limits

Everything here is automatic for every kept site and costs nothing extra: the generated `robots.txt`, `sitemap.xml` and `llms.txt`, IndexNow, `seo` hints, search settings and the **Get found** tab. A site published without an account is always `noindex`. A site is **findable** only when it is kept (claimed), past the free wait if it has one, public (no site passcode or password, not invite-only) and online (not archived, paused, frozen or offline over the plan). Otherwise its responses carry `X-Robots-Tag: noindex`, and `seo.reason` says why (`seo.indexable` is the flag). Custom domains, visitor sources, `lead_source` and leads by source in the weekly report depend on the plan: https://pagelemon.com/pricing.

- **The free wait:** a kept site with the badge (Free) is hidden for its first 7 days so scam sites can be stopped; `seo.reason` is `new` with the exact date in `indexable_from`. A paid plan or a live custom domain makes it findable at once: offer that if the person is in a hurry (https://pagelemon.com/pricing), never pressure.
- On Free, the `<name>.pagelemon.dev` address is the main address. A custom domain needs a paid plan (https://pagelemon.com/agents/domains, https://pagelemon.com/pricing); say so once, never retry.
- The generated sitemap lists at most 5,000 pages and `llms.txt` at most 500; hints check up to 1,000 pages. Say plan names, never ids.

## Ask the person

In one message, with defaults:

1. **What they do, in their customers' words, and where** ("hairdresser in Leeds", "online piano lessons, UK-wide"). This drives titles, descriptions and headings.
2. **Their name, address, phone and opening hours, exactly as they want them everywhere** (NAP). Never invent them; offer to use what is already on the site.
3. **The questions customers ask most** (aim for 5-10), with their answers.
4. **Their profiles and listings** (Google Business Profile, Instagram, Facebook, Yelp, Tripadvisor) for `sameAs`.
5. **AI training and AI answers.** Default: both allowed. Only ask if they raise it, and never suggest blocking AI answers for a business that wants customers.

## What the person needs ready

- Their business details (above). Where to find them: the Google Business Profile at google.com/business, or their invoices and signage.
- Photos (through `create_upload_link`, https://pagelemon.com/agents/edit).
- For Search Console or Bing Webmaster Tools: a Google or Microsoft account. They copy the verification file name or meta tag from the tool and paste it to you (steps below).

## Set it up

**Order matters.** For a local business the biggest levers are off the site: the Google Business Profile, other listings and reviews (the first subsection below; give the person those steps every time), then one page per service and place, then the page details. Tell the person plainly: "Page Lemon has done the technical part; your Business Profile, reviews and one page per service are yours, and I can help with the pages." Alt text, `lang`, one `h1`, heading order and link text help people using screen readers as much as search engines: say so.

Read pages with `get_site` and `path` first. The settings and steps are below; the page markup is in "Put it on the page".

### Listings and reviews (tell the person, first)

You can't create these for them, and Page Lemon doesn't submit to directories. Give the steps, in this order:

1. **Google Business Profile** (the biggest lever for maps, local results and Google's AI answers): google.com/business → business name, category, address or service area, phone, hours, website (the main address, tagged `?utm_source=google-business&utm_medium=profile`) → verify (Google picks: phone, text, email or video) → photos and a description.
2. **Bing Places** (bingplaces.com): import from the Google Business Profile. Bing feeds Microsoft Copilot.
3. **Apple Business Connect** (businessconnect.apple.com): Apple Maps and Siri.
4. **One or two directories** for their trade or area (Yelp, Facebook, Tripadvisor, a trade body).
5. **Reviews:** the Business Profile's **Ask for reviews** link, sent to happy customers; offer to add a "Leave us a review" link to the site's thank-you message after a booking or a form send (the plugin's success message or thank-you page). They reply to every review. Never write or invent reviews, and add no `Review`/`AggregateRating` markup for the site's own reviews (Google ignores self-serving review stars).

Name, address and phone identical everywhere, character for character, including the site footer and JSON-LD.

### Main address and other addresses

The main address (`seo.main_url`) is the site's main custom domain when one is live, else `https://<name>.pagelemon.dev`. With several live custom domains (`www.example.co.uk` and `example.co.uk`) it is the `primary_domain` setting when that domain is live, else the one connected first. Every file on the site's **other** addresses is served with `Link: <https://<main host><path>>; rel="canonical"` and nothing else (no `noindex`), so rankings move across to the main address and the other addresses keep working (previews, old links). No redirect unless the Site Owner turns on `domain_redirect` (then a `301` to the same path on the main address, cached for an hour). It is off by default because a domain that breaks would send visitors from every address to it until it stops being the main address (the 301 is cached for an hour): suggest it only once the domain has been live for a while.

### robots.txt, sitemap.xml and llms.txt

When the live version has no file of that name at the root, Page Lemon answers it itself. **A site's own file always wins** and is served as written.

- **`robots.txt`** on a public site, findable or not yet: `User-agent: *`, `Allow: /` (while a site is hidden, the `noindex` header does the hiding, so crawlers must be allowed to see it); a `Disallow: /` group for the AI-training crawlers with `ai_training: "block"` (GPTBot, ClaudeBot, anthropic-ai, Google-Extended, Applebot-Extended, CCBot, Bytespider, Meta-ExternalAgent, cohere-ai, cohere-training-data-crawler); a `Disallow: /` group for the AI-answer crawlers and fetchers with `ai_answers: "block"` (OAI-SearchBot, ChatGPT-User, Claude-SearchBot, Claude-User, PerplexityBot, Perplexity-User, DuckAssistBot, MistralAI-User, Amazonbot); then `Sitemap: https://<main host>/sitemap.xml`. A site with a passcode or invite-only always gets `Disallow: /`, even when it has its own file.
- **`sitemap.xml`:** the site's pages on the main address (`index.html` → `/`, `menu/index.html` → `/menu/`, `about.html` → `/about.html`) with `<lastmod>` = when the page's content last changed. Left out (also from `llms.txt`, pings and hints): `404.html`, search-engine verification files (`google<token>.html`, `yandex_<token>.html`, `pinterest-<token>.html`), pages with a `noindex` robots meta tag, protected paths.
- **`llms.txt`:** the home page title and description, then each page's title, main-address URL and description. Not generated with `ai_answers: "block"`. Few AI tools read it: don't spend the person's time on it or present it as a benefit.

Write your own file only when you need more: hreflang alternates in the sitemap (sites in several languages) or crawler rules of your own. Then you keep it up to date: your sitemap on the main address without locked paths, a `Sitemap:` line in your `robots.txt`, and the AI switches no longer change it. To go back to the generated file, delete yours (`publish_site` with `patch: true` and `deleted`).

### Search settings

Site Owner (`manage`), kept sites, every plan. MCP: `save_site_settings` with `site` and `search` (on its own). Both return `{search, seo, agent_message}`; Site Developers and viewers get `403`.

```json
{ "site": "maison-cafe", "search": { "ai_training": "block", "review_url": "https://g.page/r/XXXX/review" } }
```

- `ai_training: "allow" | "block"` (default `allow`): asks AI companies not to train on the site. It doesn't affect AI answers, nor Google's AI Overviews or AI Mode.
- `ai_answers: "allow" | "block"` (default `allow`): asks AI search and assistants (ChatGPT search, Claude, Perplexity…) not to read the site; it then also stops appearing in their answers. Rarely what a business wants: say so before setting it.
- Both are robots.txt requests that the major companies honour, not a guarantee: never tell the person their site is "protected" from AI.
- `primary_domain: "<hostname>" | null`: one of this site's custom domains (used once live); `null` goes back to the first connected.
- `domain_redirect: boolean` (default `false`): see "Main address" above.
- `review_url: "https://…" | null` (https only, at most 500 characters): where customers leave a review, such as the Google review link. It shows in the Get found checklist and comes back as `seo.settings.review_url`: add it to the site's thank-you message or page ("Leave us a review").
- `steps: {gbp?, bing?, apple?, search_console?, review_link?: boolean}`: the person's checklist ticks (Google Business Profile, Bing Places, Apple Business Connect, Search Console, review link shared). Tick one only when the person says they've done it. On paid plans the weekly report names the next unticked step for a findable site.

The app has the same controls: the site → **Get found** ("Let AI companies learn from this site" is `ai_training`, "Show this site in AI answers" is `ai_answers`, "Send visitors on other addresses to the main domain" is `domain_redirect`). Use those names with the person.

### The `seo` read-back and its hints

`publish_site` and `restore_version` replies and `get_site` without `path` carry `seo`: `{indexable, reason, indexable_from?, main_url, sitemap_url, llms_url, robots_url, own_files: {robots, sitemap, llms}, pages, settings, automatic, hints, setup_note?, guide_url}`.

- `reason` (null when findable): `not_kept` (give the keep link, https://pagelemon.com/agents/publish), `new` (say the exact date in `indexable_from`), `private` (a passcode or invite-only), `archived`, `paused` (frozen or over the plan), `home_noindex` (the home page has a `noindex` meta tag: remove it unless it is on purpose).
- `automatic`: what Page Lemon does for this site now (`main_address`, `sitemap`, `robots`, `indexnow`; `main_address` only with a live custom domain, `indexnow` only when findable).
- `setup_note` (the first time, or when something new turns on): pass it on to the person in their language, in plain words.
- `hints`: at most 8, most important first, each `{code, text, pages?}` (up to 5 paths). They never block a publish. Fix what you can with the person and patch-deploy:

| `code` | The fix |
|---|---|
| `noindex_on` | Remove `<meta name="robots" content="noindex">` from those pages, unless the person wants them hidden |
| `title_missing` / `title_duplicate` | A unique `<title>` per page (patterns under "Put it on the page") |
| `nap_missing` | Show the phone number (and address) on the site, in the footer of every page |
| `nap_mismatch` | Make the JSON-LD `telephone` the same as the number shown on the pages |
| `description_missing` | A unique `<meta name="description">` per page |
| `h1_missing` / `h1_many` | Exactly one `<h1>` per page |
| `services_one_page` | Give each main service its own page, linked from the navigation |
| `location_missing` | Name the town or area (the JSON-LD `addressLocality`) in the home page title or `h1` |
| `viewport_missing` | Add the viewport meta tag |
| `image_heavy` | Resize and compress images (under 300 KB, ideally under 200 KB) and add `width` and `height` |
| `lang_missing` | `<html lang="…">` on every page |
| `canonical_wrong_host` | Point the canonical at this site, or remove it (Page Lemon sets one) |
| `img_alt_missing` | `alt` on each image: what it shows, or `alt=""` for decoration |
| `jsonld_missing` | JSON-LD on the home page; for a local business, `LocalBusiness` with name, address, phone and hours |
| `og_image_missing` | An `og:image` (1200×630, absolute URL) on the home page |

### Search Console and Bing verification

1. The person opens https://search.google.com/search-console → **Add property** → **URL prefix**, enters the main address (`seo.main_url`), and picks **HTML file** (the easiest for you; the **HTML tag** works too).
2. They paste you the file name (`google<token>.html`), or the tag (`<meta name="google-site-verification" content="…">`).
3. You add the file at the site root with exactly the content Google gives (`google-site-verification: google<token>.html`), or the tag in the home page `<head>`, then patch-deploy. Keep it: removing it unverifies the site.
4. They press **Verify**, then **Sitemaps** → submit `sitemap.xml`.
5. Bing: https://www.bing.com/webmasters → **Import from Google Search Console**. It verifies Bing and brings the sitemap with no second file.

Verify the address they share (the custom domain once it is live). Never ask for their Google password or account access.

### Campaign tags (utm)

Page Lemon records `utm_source`, `utm_medium` and `utm_campaign` from the page address: Visitors **Sources** (paid plans) show `utm_source` (else the referring site), and each form reply, booking and order stores the page and the tags as `lead_source` (https://pagelemon.com/agents/analytics). Advise: lower case, dashes instead of spaces, one fixed word per channel (`instagram`, `newsletter`, `flyer`, `google-business`), `utm_medium` for the kind (`bio`, `email`, `qr`, `post`), `utm_campaign` for a dated push (`summer-sale`). Tag the Google Business Profile website link with `?utm_source=google-business&utm_medium=profile` so map traffic is told apart. Tags are for places, not people: never a name, email address or phone number, and never one link per recipient. Never tag internal links. The app's **Get found** → **Track a link** builds tagged links from presets (the first is the Business Profile website link), and the Google Business Profile step there shows that tagged address with a Copy button; Visitors shows the source `google-business` as "Google Business Profile".

### Content AI answers use

- **Answer first:** each FAQ answer starts with the direct answer in one sentence, then the detail.
- **Facts with numbers:** prices, durations, hours, areas, years, capacities ("from £18", "45 minutes", "within 10 miles of Leeds").
- **Entity consistency:** the same business name, address, phone, description and profile links everywhere (site, JSON-LD, Business Profile, listings).
- **One topic per page,** with a heading that names it; a short summary at the top of long pages.
- **Plain HTML text,** not text inside images; key facts not hidden behind tabs that need JavaScript.

## Confirm with the person

Before deploying a search pass, show the person in one message: the title and description you'll use for each page, the business details as they will appear in the footer and JSON-LD, and the FAQ. Deploy after their yes. Search settings change who reads the site or where visitors land: before `ai_answers: "block"` say it makes AI answers much less likely to mention them (`ai_training` doesn't); before `domain_redirect: true` say both addresses then depend on the domain's DNS. Set either only after their yes.

## Put it on the page

The markup for every public page, then patch-deploy (`publish_site` with `patch: true`, `base_version`).

### Each page

- **One page per service, and the place:** each main service gets its own page (`/mens-haircuts.html`), naming the town or area in its title, `h1` and first paragraph; a service-area business names the areas it covers. Don't cram every service onto the home page.
- **`<title>`:** unique, 50-60 characters, the page's subject first, then the business and place: `Men's haircuts in Leeds | Fade Barbers`; home page: `Fade Barbers: barber in Leeds city centre`.
- **`<meta name="description">`:** unique, 120-155 characters, what the page offers and a reason to click: `Walk-in and booked haircuts from £18, open 7 days on Call Lane, Leeds. Book online in a minute.`
- **One `<h1>`** saying what the page is about; `h2`/`h3` in order, no skipped levels, written as the words people search ("Prices", "Opening hours", "How to find us").
- **Canonical: don't hard-code one.** Page Lemon sends the canonical itself, and in every served page rewrites a `<link rel="canonical">` or `og:url` that points to another address of this site (its `pagelemon.dev` address, any domain it has or had) to the main address, so pages stay right when a domain goes live. If you write one (a template already has one), any address of this site is fine; never point it at another host (hint `canonical_wrong_host`). Absolute links in JSON-LD `url` and your own sitemap should use `seo.main_url`.
- **Open Graph:** `og:title`, `og:description`, `og:type` (`website`), `og:image` (absolute URL, 1200×630, under 300 KB, JPEG or PNG), `og:locale`; `twitter:card` `summary_large_image`.
- **`<meta name="viewport" content="width=device-width, initial-scale=1">`** and **`<html lang>`** on every page. Several languages: one folder per language, `hreflang` alternates on every page including `x-default` (https://pagelemon.com/agents/languages).
- **Images:** `alt` on every meaningful image (what it shows, plainly; `alt=""` for decoration); `width` and `height` attributes; at most about 1600 px wide, WebP or AVIF with a JPEG fallback when it matters, under 200 KB each (hint `image_heavy` over 300 KB or without `width`/`height`); `loading="lazy"` on images below the first screen, never on the main image at the top.
- **Speed:** fonts self-hosted (woff2, `font-display: swap`) or system fonts; no unused scripts; CSS in one file. Page Lemon caches pages at the edge.
- **Internal links:** every page reachable from the navigation; descriptive link text ("See our prices", not "click here"); service pages link to booking or contact.
- **404 page:** a `404.html` that links home. Page Lemon answers a real 404 for missing pages on multi-page sites.

### Structured data (JSON-LD)

One `<script type="application/ld+json">` on the home page (and the matching type on other pages), with values identical to the visible footer.

- **`LocalBusiness` or its closest subtype** (`HairSalon`, `BarberShop`, `Restaurant`, `CafeOrCoffeeShop`, `Dentist`, `Plumber`, `Electrician`, `ProfessionalService`, `HealthAndBeautyBusiness`, `SportsActivityLocation`, `Store`…): `name`, `url`, `telephone`, `email`, `image`, `logo`, `priceRange`, `address` (`PostalAddress`: `streetAddress`, `addressLocality`, `postalCode`, `addressCountry`), `geo` (`GeoCoordinates`, from the person's map pin; never guessed), `openingHoursSpecification` (one entry per set of days, 24-hour `opens`/`closes`), `areaServed` for a service-area business with no public address, `sameAs` (their profile URLs).
- **`Service`** per service page (`name`, `description`, `provider` → the business, `areaServed`, `offers` with `price` and `priceCurrency` when there is a fixed price).
- **`Product` with `Offer`** for things sold (`name`, `image`, `description`, `offers.price`, `priceCurrency`, `availability`).
- **`FAQPage`** for a questions section: each `Question.name` and `acceptedAnswer.text` repeat the visible question and answer word for word.
- **NAP:** name, address and phone identical in the footer, JSON-LD, contact page and the person's Google Business Profile, character for character.
- **Templates:** every `data-pl-fill` element and the fictional sample business must be replaced in the HTML and in the JSON-LD before the site is shared (https://pagelemon.com/agents/templates); the JSON-LD is where sample values are most often missed.
- No `Review` or `AggregateRating` markup for reviews the site collects about itself, and never invented reviews.

## Test

1. After the deploy, read `seo` in the reply: no hints left that you could fix, and `indexable` true, or a `reason` you have explained.
2. `get_site` each page and check: one `h1`, title and description present and unique, canonical on the main address, alt on images, JSON-LD values equal to the footer.
3. Fetch `seo.robots_url`, `seo.sitemap_url` and `seo.llms_url` and check they list what you expect (the sitemap: every public page, on the main address).
4. Suggest the person paste the home page into https://search.google.com/test/rich-results to check the structured data.
5. Tell the person the result before saying it's ready: what Page Lemon does automatically (`setup_note`), when the site can be listed (`indexable_from` if still hidden), the next steps only they can do (Google Business Profile, Search Console), and that showing up takes weeks. They can see the same in the app: the site → **Get found**.

## Day to day

- After any content change, keep titles, descriptions and JSON-LD in step with the page.
- New page: nothing to do with the generated sitemap and `llms.txt` (they follow the live version, and IndexNow is pinged); add it to your own if the site has them.
- A custom domain goes live: it becomes the main address (Page Lemon re-pings every page). Page Lemon corrects same-site canonicals and `og:url` when serving; update JSON-LD `url` and absolute links in your own files, then have the person add the domain in Search Console and submit its sitemap.
- Open the app's **Get found** tab with the person for the status, the hints and the **Track a link** helper. Use `get_analytics` to show the person which sources bring visitors (https://pagelemon.com/agents/analytics).

## What Page Lemon refuses, and the fix

| What happens | The fix |
|---|---|
| `seo.reason` `not_kept` or `new` (`noindex`) | Keep the site (https://pagelemon.com/agents/publish); a new free site can be listed from `indexable_from`, or at once with a paid plan or a live custom domain. Nothing to fix in the pages |
| `seo.reason` `private`, or locked pages not listed | Expected; a site or path with a passcode or invite-only is never listed. Remove the lock only if the person wants those pages found |
| `seo.reason` `archived` or `paused` | Unarchive (https://pagelemon.com/agents/edit), or the plan needs attention (https://pagelemon.com/pricing) |
| `seo.reason` `home_noindex` | Remove the `noindex` robots meta tag from the home page |
| The site's own `robots.txt`, `sitemap.xml` or `llms.txt` is served instead of Page Lemon's | Expected: the site's file wins. Delete it (`publish_site` `patch: true`, `deleted`) to get the generated one back |
| `ai_training` or `ai_answers` changed but `robots.txt` didn't | The site has its own `robots.txt`; write the crawler rules into it, or delete it |
| `save_site_settings` `search` from a Site Developer or viewer: `403` | Only the Site Owner changes search settings; ask them, or they use the app (**Get found**) |
| A `primary_domain` that isn't one of this site's custom domains is refused | Use a hostname from `get_site` for this site, or `null` |
| A `review_url` that isn't `https`, or is too long, is refused | An `https` link of up to 500 characters (the Google review link), or `null` |
| A custom domain refused on Free | Paid plan needed; link https://pagelemon.com/pricing, don't retry |
| Search Console can't verify | The file at the root with Google's exact content, or the tag in the home page `<head>`, on the same address the property uses (the main address); redeploy and press Verify again |

## Links

- The guide for the person: https://pagelemon.com/docs/seo
- Your own domain: https://pagelemon.com/agents/domains · Languages: https://pagelemon.com/agents/languages · Analytics: https://pagelemon.com/agents/analytics
- API and MCP reference: https://pagelemon.com/docs/api, https://pagelemon.com/docs/mcp
- All guides: https://pagelemon.com/agents
