/ โ† Agent Readiness Fixes / JSON-LD Coverage
In this guide
  1. What coverage actually means
  2. Which types suit which pages
  3. Describe the business once, refer to it everywhere
  4. A complete block for a service page
  5. The gaps audits find most often
  6. Building a coverage matrix
  7. The fix, step by step
  8. What JSON-LD will and will not do
  9. Questions and answers

What coverage actually means

JSON-LD coverage is not a count of pages with a <script type="application/ld+json"> block. A page can have one and still say almost nothing. The Agent Readiness Audit reviews coverage as four separate questions, and a gap in any of them is worth fixing:

  1. Breadth. Does every template that describes something real, such as a service, a product, a location, a person or an article, output structured data?
  2. Type. Is the main entity described with a type that matches what the page is about, rather than a generic WebPage or a copied Article?
  3. Depth. Are the properties that hold the useful facts present: price, address, opening hours, author, dates, area served?
  4. Connection. Do the page, its main entity and the organisation behind the site link together, so a machine can see they belong to one business?

Structured data states in a fixed vocabulary what the visible page already says. It does not replace the visible text, and it must match it. Its value for AI crawlers is that it removes ambiguity: a price marked as a price, in a stated currency, attached to a named service, is harder to misread than a number in a paragraph.

Which types suit which pages

Use the most specific schema.org type that honestly describes the page's main subject. The table below covers the templates most small-business sites have. Every page can also carry a WebPage (or a more specific kind such as AboutPage or ContactPage) and a BreadcrumbList.

TemplateMain entity typeProperties that carry the facts
Home pageOrganization or a LocalBusiness subtype, plus WebSitename, url, logo, address, telephone, sameAs
Service pageServicename, description, provider, areaServed, offers with price and priceCurrency
Location or branch pageLocalBusiness subtype such as Plumber or Dentistaddress, geo, openingHoursSpecification, telephone, parentOrganization
Product pageProductname, image, sku or gtin, brand, offers with price, priceCurrency and availability
Category or collection pageCollectionPage with an ItemListitemListElement with each item's url and name
Article, guide or newsArticle or BlogPostingheadline, author, publisher, datePublished, dateModified, image
About pageAboutPage about the OrganizationfoundingDate, founder, employee or member where relevant
Contact pageContactPagethe organisation's contactPoint, telephone, email, address
Team or author pageProfilePage about a Personname, jobTitle, worksFor, sameAs
Event pageEventstartDate, endDate, location, eventStatus, offers

Schema.org is broader than what Google shows as rich results, and the two should not be confused. Google removed HowTo rich results in 2023 and limits FAQ rich results to well-known authoritative government and health sites, but HowTo and FAQPage remain valid schema.org types that describe content accurately. Mark content up because the description is true, not only because a search feature exists for it.

Describe the business once, refer to it everywhere

The most common coverage gap is not a missing page type but a missing publisher. Each template outputs its own small block, and none of them says which business the page belongs to. The fix is to describe the organisation, and the website, once in full, give each a fixed @id, and have every other page refer to those identifiers.

How identifiers work in detail, and the problems that occur when references point to nothing, are covered in the schema references guide. For coverage, the point is simply that every template should connect to the same business rather than float on its own.

A complete block for a service page

Service pages are the template most often left bare, and often the one that answers the questions people put to AI assistants: what does it cost, where do they work, who provides it. This example for a fictional drainage company shows a service page described fully and connected to the business.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "WebPage",
      "@id": "https://www.example.co.uk/services/cctv-drain-survey/#webpage",
      "url": "https://www.example.co.uk/services/cctv-drain-survey/",
      "name": "CCTV drain surveys in Leeds and Wakefield",
      "isPartOf": { "@id": "https://www.example.co.uk/#website" },
      "mainEntity": { "@id": "https://www.example.co.uk/services/cctv-drain-survey/#service" },
      "breadcrumb": { "@id": "https://www.example.co.uk/services/cctv-drain-survey/#breadcrumb" }
    },
    {
      "@type": "Service",
      "@id": "https://www.example.co.uk/services/cctv-drain-survey/#service",
      "name": "CCTV drain survey",
      "serviceType": "Drain inspection",
      "description": "Camera inspection of domestic drains with a written report and recorded footage.",
      "provider": { "@id": "https://www.example.co.uk/#organization" },
      "areaServed": [
        { "@type": "City", "name": "Leeds" },
        { "@type": "City", "name": "Wakefield" }
      ],
      "offers": {
        "@type": "Offer",
        "price": "145.00",
        "priceCurrency": "GBP",
        "description": "Standard domestic survey, including VAT"
      }
    },
    {
      "@type": "BreadcrumbList",
      "@id": "https://www.example.co.uk/services/cctv-drain-survey/#breadcrumb",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Services", "item": "https://www.example.co.uk/services/" },
        { "@type": "ListItem", "position": 2, "name": "CCTV drain survey" }
      ]
    }
  ]
}
</script>

The organisation and website are not repeated here; they are described on the home page and referenced by identifier. Every value in the block, including the price and the towns served, must also appear in the visible text of the page. If the price changes, the markup must change with it, which is a strong argument for generating it from the same data the page uses.

The gaps audits find most often

GapWhat it looks likeFix
Uncovered templatesPosts have markup; services, locations, categories and contact have noneAdd a template-level block for each, using the table above
Stub entitiesA LocalBusiness with a name and nothing elseAdd address, telephone, opening hours and url from your business details
Wrong main typeProduct and service pages marked as Article because the plugin default was left onSet the type per template, not site-wide
Markup injected by a tag managerPresent in the browser inspector, missing from the page sourcePrint it in the server HTML; many AI crawlers do not run scripts
Orphaned entitiesEach block describes something but none names the businessReference the organisation by @id from every template
Stale valuesPrice, hours or availability in the markup no longer match the pageGenerate markup from the same fields the page displays
Parallel duplicatesTheme, plugin and app each output their own version of the same entityChoose one source per type and switch off the others
โš ๏ธ Do not fill gaps by marking up things the page does not show, such as reviews you hold elsewhere, ratings from another site or an address you only mention in the footer of a different page. Markup that describes invisible or unrelated content can lead Google to ignore your structured data or take manual action, and it misleads other systems too.

Building a coverage matrix

Coverage is a template problem, so measure it by template. A simple spreadsheet is enough.

  1. List each template down the side: home, service, location, product, category, article, about, contact, team, event.
  2. For each, take one representative URL and fetch the raw HTML, so you see what non-rendering crawlers see:
    curl -s https://www.example.co.uk/services/cctv-drain-survey/ \
      | grep -c 'application/ld+json'
  3. Paste the URL into the Schema Markup Validator at validator.schema.org, which checks against the full schema.org vocabulary, and note every type found and its properties.
  4. Where Google offers a rich result for the type, also run the Google Rich Results Test, which checks Google's required and recommended properties.
  5. Add columns for the four questions: breadth, type, depth and connection. Mark each cell as done, partial or missing.

Compare the validator results with what you see in the browser inspector. Markup that appears in the inspector but not in the curl output is being added by JavaScript, and should be moved to the server. The finished matrix becomes your work list and, later, your regression check.

The fix, step by step

Step 1

List your templates and what each page is about

Write down every page template on the site and, for each one, the real-world thing its pages describe: a service, a product, a branch, a person, an article, a list of items or the business itself. Include the pages people forget, such as contact, about, team and location pages. This list decides which schema.org type each template needs, so describe the subject in plain words before thinking about vocabulary.

Step 2

Record what markup each template outputs now

For one URL per template, fetch the raw HTML with curl, count the JSON-LD blocks, and run the page through the Schema Markup Validator. Record the types and properties found in a coverage matrix. Note where markup appears only in the browser inspector, where several tools output overlapping blocks, and where a template has no markup at all. That matrix is your starting position and your plan.

Step 3

Describe the site-wide entities once

On the home page or about page, describe the organisation fully with its name, logo, address, telephone and official profiles, and describe the website. Give each a permanent @id based on your canonical home address. Remove partial copies of the organisation from other templates and replace them with references to that identifier, so every page connects to one complete description of the business.

Step 4

Choose a primary type for each template

Match each template to the most specific honest schema.org type: Service for service pages, a LocalBusiness subtype for branches, Product for products, CollectionPage with an ItemList for categories, Article for editorial content. Set the type at template level rather than relying on a single site-wide default, and link each main entity to its WebPage with mainEntity. Where a page covers several things, pick the one it is mainly about.

Step 5

Fill in the properties that carry the facts

For each type, add the properties that hold what customers ask about: prices with currency, addresses, opening hours, areas served, availability, authors and dates. Take every value from the same CMS fields the visible page uses so the two cannot drift apart. Leave out anything not shown on the page. Check Google's documentation for required properties where a rich result exists for that type.

Step 6

Output the markup from the server

Move any JSON-LD currently added through a tag manager or client-side script into the server-rendered template, so it is present in the first HTML response. Where a theme, plugin and app each output the same type, choose one source and switch off the others. Fetch each template with curl and confirm the block appears once, is complete, and matches the visible text.

Step 7

Validate every template and repeat on change

Run each representative URL through the Schema Markup Validator and, where relevant, the Rich Results Test, and fix every error. Update the coverage matrix to show each template as covered. Run the Agent Readiness Audit again to confirm the coverage findings have cleared. Keep the matrix and repeat the check whenever a template, theme, plugin or product data feed changes.

What JSON-LD will and will not do

It is worth being clear about expectations. Structured data is a way of stating facts precisely. It does not make a thin page useful, and it does not oblige any search engine or AI system to show or cite your page.

๐Ÿ’ก If a fact matters enough to mark up, it matters enough to write clearly in the page text as well. The content extractability guide covers the visible side.
Questions and answers

1. Which pages should have JSON-LD?

Every template whose pages describe something real should have it: the home page for the organisation and website, service and product pages, location or branch pages, articles, category pages, and the about, contact and team pages. Utility pages such as the basket, account area or internal search results usually do not need their own markup. Coverage is measured by template, so fixing the service template once covers every service page built from it.

2. Is a WebPage block on every page enough?

It is a start, but it describes only the page, not the thing the page is about. A service page marked only as a WebPage tells a machine nothing about the service, its price or where it is offered. Add a main entity of the appropriate type, such as Service, Product or LocalBusiness, fill in the properties that hold the facts, and link it to the WebPage with the mainEntity property so the relationship between page and subject is stated.

3. Do AI crawlers read JSON-LD added by Google Tag Manager?

Google renders JavaScript and can process structured data added by scripts, although it recommends server output where possible. Many AI crawlers read only the HTML the server sends and do not run scripts, so markup added by a tag manager may never reach them. If you want the markup to be available to every crawler, print it in the page template on the server. Compare the curl output with the browser inspector to see which method your site uses.

4. Should I still use FAQPage and HowTo markup?

They remain valid schema.org types, and marking up content that really is a set of questions and answers or a set of steps is accurate. What changed is Google's display: HowTo rich results were removed in 2023, and FAQ rich results are now limited to well-known authoritative government and health sites. So do not add them expecting enhanced search listings. Add them only where the content genuinely has that shape, and keep them consistent with the visible text.

5. What is the difference between the Schema Markup Validator and the Rich Results Test?

The Schema Markup Validator checks your markup against the whole schema.org vocabulary and shows every type and property it finds, whether or not Google does anything with them. The Rich Results Test checks only the types that can produce Google rich results and reports Google's required and recommended properties for those. Use the validator to confirm your coverage and structure, and the Rich Results Test for pages where a Google feature is relevant, such as products or events.

6. How many JSON-LD blocks can one page have?

There is no fixed limit, and several blocks on one page are valid. Problems arise when two blocks describe the same thing differently, for example a theme and a plugin both outputting an Article with different authors or dates, or two Organization descriptions with different names. A single block containing an @graph with each entity described once is the tidiest approach, but separate blocks are fine as long as they do not contradict each other.

7. Can I add markup for reviews or ratings I hold on another site?

No. Structured data should describe what the page itself shows. Marking up ratings or reviews that visitors cannot see on the page, or that were collected and are displayed elsewhere, goes against Google's structured data guidelines and can lead to the markup being ignored or to a manual action. If reviews matter to your business, display them on the page in text that the server sends, and then mark up what is shown.

See which templates are missing structured data

The Agent Readiness Audit requests your page with real AI crawler user agents, checks robots.txt and llms.txt, reviews JSON-LD coverage and semantic HTML, tests how much depends on JavaScript and measures how easily the content can be extracted.

Open Agent Readiness Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Agent Readiness Fixes  ·  Broken Schema References  ·  Author and Trust Signals  ·  JSON-LD in WordPress  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.