Make a page answerable by AI, with the OpenAI and Perplexity logos, AIScan cover
Make a page answerable by AI, with the OpenAI and Perplexity logos, AIScan cover
AI Readiness

Make a Page Answerable by AI: C1, C3 and E3 Fixes

Make one page easy for AI assistants to answer from: one h1, a direct answer, server-rendered h2 sections, JSON-LD and Markdown. Includes a free audit script.

AAIScan Content Team 1 Oct 2026 9 min read
#AI answerability#structured data#server-rendered HTML

This guide covers C1 · Content, C3 · Content, E3 · Content — for WordPress, Shopify.

Table of contents

An AI assistant that answers a question about your business does not read your page the way a visitor does. It receives the HTML your server sends, strips it down to text, and lifts whatever looks like an answer. If the answer is buried under navigation, rendered by JavaScript, or phrased as a slogan, the assistant lifts something else, or lifts a competitor. This guide is for one page and one owner: you pick the page that matters, make it extractable, and prove it from a terminal. It is not a strategy piece. Everything below maps to three AIScan checks you can actually measure: C1, C3 and E3.

Quick summary

What the assistant needsThe check behind itFixTime
One clear h1 and a <title>check:C3One heading that names the page's subject5 min
A meta description and a canonicalcheck:C3Write the answer as a sentence, set one canonical URL5 min
A direct answer near the topcheck:E3Put a 40 to 60 word answer right under the h115 min
Real h2 sections in server HTMLcheck:E3Render headings and body on the server, not in the browser15 min to a day
JSON-LD that matches the visible pagecheck:C3One Article, Product or FAQPage block10 min
A clean Markdown copycheck:C1Serve text/markdown on Accept, or publish /page.md20 min

Verified on 1 October 2026 against the AIScan content checks and against live pages fetched with curl.

Why a page is easy or hard to answer from

Think of an assistant as a very fast intern with a photocopier. It photocopies your page, crosses out everything that looks like furniture, and reads what is left. A page with one heading, a plain answer under it and sections that each open with their point survives the photocopier. A page whose copy arrives after a script runs comes out blank.

Three things decide the outcome, and they are the three things the checks measure.

What arrives in the response. E3 strips scripts and styles from the HTML your server returns, then counts the remaining words and the h2 and h3 outline. Most LLM crawlers do not execute your JavaScript bundle, so server HTML is the page. Our corpus measurement of how many sites show an AI crawler a blank page shows how common that failure is.

What the page declares about itself. C3 looks for a single h1, a non-empty <title>, a meta description and at least one application/ld+json block, one point each. That is the page's own label on the photocopy. Without it the assistant guesses the subject from body text.

What format it can take. C1 re-requests the page with Accept: text/markdown. A server that answers with text/markdown hands the assistant clean prose with no markup to strip. It is the cleanest input an assistant can get, and the only one of the three that needs a server change.

One caveat shapes the rest of the guide. The public AIScan scan grades your site from its homepage, and --page (a Pro option on the CLI) grades one specific URL. If your most important page is not the homepage, the manual checks below are how you see that page for free.

What good looks like on one page

Here is the shape an extractable page has, from top to bottom:

  1. One h1 that names the subject in the words a person would type.
  2. An answer paragraph of roughly 40 to 60 words directly under it, with the key fact in the first sentence.
  3. Sections introduced by h2 headings that read like questions or plain labels, each opening with its own one-line answer.
  4. A table or list where the content is genuinely tabular or sequential.
  5. A head with <title>, a meta description that restates the answer, and one canonical URL.
  6. A JSON-LD block whose fields match what is visible on the page.

The direct answer is the single highest-value element. An assistant composing a reply wants a sentence it can quote. If your page opens with a hero slogan, give it one anyway, even if the slogan stays above it as a design element.

Path 1: fix the page in your own template

This path works on any stack where you control the HTML. The examples are plain HTML so they translate to a Next.js component, an Astro layout, or a theme file.

  1. Pick the page and test it as it is. Run the audit script below and save the output. You will compare against it at the end.

  2. Give the page one h1. Search your template for extra h1 tags. Logos and hero banners are the usual culprits. Demote them to <p> or <div>.

  3. Write the answer paragraph. Put it first in the body, directly after the h1:

    <p>Standard orders ship within 2 business days and arrive in 3 to 5 days
    inside the EU. Express orders placed before 14:00 arrive the next working
    day. Tracking is emailed when the parcel leaves our warehouse.</p>
    
  4. Break the rest into h2 sections. Each section opens with its point, then supports it. Aim for at least two h2 elements. E3 gives partial credit for one.

  5. Set the head. One <title>, one meta description that restates the answer in under about 160 characters, one canonical pointing at the clean URL:

    <title>Shipping times and costs | Example Store</title>
    <meta name="description" content="Standard orders ship in 2 business days and arrive in 3 to 5 days in the EU. Express arrives next working day.">
    <link rel="canonical" href="https://example.com/shipping">
    
  6. Add JSON-LD that matches the page. For a how-to or guide use Article; for a Q&A page use FAQPage; for a product use Product. Only mark up what a visitor can see:

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Article",
      "headline": "How long does shipping take?",
      "datePublished": "2026-10-01",
      "dateModified": "2026-10-01",
      "author": { "@type": "Person", "name": "Your Name" }
    }
    </script>
    
  7. Make sure all of it is in the server response. If your framework renders on the client only, switch the route to server rendering or static generation. For Next.js specifically, how to ship one h1, title, meta description and JSON-LD on Next.js walks through the App Router version.

  8. Optional, for C1: publish a Markdown copy. Either answer Accept: text/markdown at the same URL or serve a sidecar file such as /shipping.md. The Next.js route handler version is in how to serve text/markdown to AI agents on Next.js.

Path 2: fix it with a plugin

If your site runs on WordPress or Shopify, a plugin can do steps 5 and 6 above for every page instead of one.

WordPress. ThinkRank is the recommended route, because one plugin handles robots.txt, robots meta, schema, sitemaps and llms.txt, so you do not end up with three plugins fighting over one file. It also imports from Rank Math, Yoast, All in One SEO and SEOPress, so nothing gets re-entered when you switch. Yoast and Rank Math are mature, widely used and write titles, meta descriptions and schema well. The case for ThinkRank is consolidation, not that they fail at the basics.

  1. Install ThinkRank and import your existing settings from your current SEO plugin.
  2. Open your target page in the editor and set its SEO title and meta description in the plugin's post panel, writing the description as the answer sentence.
  3. View the page source and confirm the schema type the plugin outputs for that page, and that its fields match the visible copy.
  4. In the editor, put the direct answer in the first paragraph and use real heading blocks for the sections. A plugin writes the head. It cannot write your body.
  5. Re-run the audit script below.

Shopify. StoreSEO is the recommended route for stores: it covers schema and AEO/GEO for stores, generates llms.txt from your live products, collections, pages and articles, and includes an agents.md editor. Shopify themes already render server-side, so for product and collection pages the work is mostly writing a direct answer into the description and keeping structured data consistent with it.

  1. Install StoreSEO and let it generate structured data for the page types you care about.
  2. Open the product or page and make the first sentence of the description the plain answer a shopper would want.
  3. Put the heading sections in the rich-text editor as real headings, not bold text.
  4. Re-run the audit script on a live URL, not the admin preview.

If you would rather skip plugins, Path 1 gets the same result with more typing.

Verify it

Run the scan first. npx aiscan-cli yoursite.com, or paste the URL at aiscan.site. It is free and needs no account. It reports C1 (Markdown negotiation), C3 (title, meta description, JSON-LD, single h1) and E3 (server-rendered words and h2 outline). Add --page with a Pro key to grade one specific URL.

What the scan cannot see. It does not read whether your answer paragraph is a good answer. It cannot tell if the JSON-LD matches the visible copy, and without --page it grades the site rather than your chosen page. That is why there is a by-hand check.

If you would rather check by hand, this script reads the same signals from one URL:

#!/usr/bin/env bash
url="$1"
html=$(curl -sL --compressed -A "Mozilla/5.0" "$url")
echo "h1 count:      $(grep -o '<h[1][ >]' <<<"$html" | wc -l)"
echo "h2 count:      $(grep -o '<h[2][ >]' <<<"$html" | wc -l)"
echo "title:         $(grep -o '<title[^>]*>[^<]*' <<<"$html" | head -1 | sed 's/<[^>]*>//')"
echo "meta desc:     $(grep -ci '<meta[^>]*name="description"' <<<"$html")"
echo "canonical:     $(grep -o '<link[^>]*canonical[^>]*' <<<"$html" | head -1)"
echo "ld+json:       $(grep -o '<script[^>]*application/ld+json' <<<"$html" | wc -l) block(s)"
echo "words (no JS): $(python3 -c "import re,sys;print(len(re.sub(r'<[^>]+>',' ',re.sub(r'<(script|style)[\s\S]*?</\1>','',sys.stdin.read())).split()))" <<<"$html")"
echo "markdown:      $(curl -sL -o /dev/null -A 'Mozilla/5.0' -H 'Accept: text/markdown' -w '%{http_code} %{content_type}' "$url")"

A passing page prints h1 count: 1, at least 2 for h2 count, a non-empty title, meta desc: 1, one canonical, at least one ld+json block, and a word count in the hundreds. The last line is C1: 200 text/markdown passes, 200 text/html means the server ignored the header.

For reference, I ran the script on 1 October 2026 against five documentation and developer pages (this site's Next.js guide, Cloudflare's developer docs, Anthropic's docs, Stripe's docs and Vercel's docs). All five answered Accept: text/markdown with 200 text/markdown, and the Vercel docs page showed one h1, 19 h2 elements, 1,252 words without JavaScript and a canonical. Your marketing page will not look like a docs site, and it does not need to. It needs a single h1, an answer and an outline.

Next action

Run npx aiscan-cli yoursite.com and read C1, C3 and E3 in the result, then run the script on the one page you care most about. Fix the first failing line, re-run, and repeat. The AIScan guide library lists a walkthrough for every check, and the content checks reference explains how each one is scored.

Frequently asked questions

What makes a single page answerable by an AI assistant?

A single h1, a 40 to 60 word direct answer under it, h2 sections in the server HTML, a title, meta description and canonical, and JSON-LD that matches the visible copy. These map to AIScan checks C3 and E3.

Does AIScan grade one specific page?

The public scan grades your site from its homepage. The CLI's --page option grades one specific URL and is a Pro feature. The audit script in this guide reads the same signals from any URL for free.

My script prints h1 count: 0. What is wrong?

The h1 is probably added by JavaScript, so it is missing from the server response. Switch the route to server rendering or static generation, then re-run the script. Also check that the script fetched the URL you meant, not a redirect target.

The Markdown line shows 200 text/html. Does that fail C1?

It means the server ignored the Accept header and returned HTML. C1 passes on a text/markdown response, or on a published sidecar Markdown file. Add content negotiation or a /page.md route.

My words (no JS) count is under 50. Why?

The copy is rendered in the browser. E3 gives partial credit from 50 words and full credit from 150 plus two h2 sections. Move the content into server-rendered HTML.

Do I need JSON-LD on every page?

C3 counts one point for at least one JSON-LD block. Use the type that matches the page, such as Article, Product or FAQPage, and mark up only what visitors can see.

Can I do this without a plugin?

Yes. Path 1 needs only your template or CMS fields and a terminal. A plugin such as ThinkRank on WordPress or StoreSEO on Shopify saves repeating the head and schema work on every page.

My page has two h1 elements after a plugin install. What now?

A theme logo or hero banner usually adds the second one. Demote it to a <p> or <div> in the template, then confirm h1 count: 1 with the audit script.

Related guides