# Brief Developer Add Schema Sprint for AI‑Ready Feature Page

> Get a brief you can give a developer to add AI‑ready schema, including JSON‑LD fields and test steps, the feature comparison page is ready in one sprint.

Source: https://comppound.com/blog/brief-developer-add-schema-sprint-for-aiready-feature-page (published 2026-10-24)

You can brief a developer with a clear five‑item checklist that covers page URL, target schema type, required properties, testing method, and delivery format, and then run it in a single sprint. The result is a feature comparison page that search engines can read as AI‑ready structured data without extra back‑and‑forth.

## What you need before the sprint
A short list of inputs lets the developer work without interruptions. Gather:

* the exact URL of the comparison page (including any query parameters you want indexed)
* the schema type you are targeting – for a feature comparison page **ItemList** with **ListItem** entries works well
* a spreadsheet of the features you are comparing, containing at least the feature name, brief description, and a link to the product page
* a test tool such as Google’s Rich Results Test or the Schema Markup Validator, and a shared folder for the final JSON‑LD file
* a deadline for delivery, typically the end of the two‑week sprint

## Step‑by‑step brief
1. **Define the page scope** – Write a short paragraph that states the page compares X‑type features for your SaaS. Include the URL and note that the schema must be placed in the `` as a JSON‑LD script. *How to verify:* open the live URL, view source, and confirm the script tag is present.
2. **Specify the JSON‑LD structure** – Provide a sample block that uses `@type: "ItemList"` and an array of `ListItem` objects. Each object should have `position`, `url`, `name`, and an optional `description`. *How to verify:* copy the sample into a sandbox, run the Rich Results Test, and look for “ItemList” without errors.
3. **Map the feature data** – Attach the spreadsheet to the brief and add a note: “Each row maps to a ListItem; position = row number, url = product page link, name = feature title.” *How to verify:* after implementation, compare the number of ListItem elements in the JSON‑LD against the row count.
4. **Define testing steps** – Ask the developer to run the Rich Results Test on the staging URL, capture the JSON output, and screenshot any warnings. Include a checklist: no “Error” messages, all required fields present, and URLs resolve to live pages. *How to verify:* the checklist is attached to the sprint ticket; once cleared, move the ticket to “Done.”
5. **Set delivery format** – Request the final JSON‑LD file be saved as `comparison-schema.json` in the repo’s `/schema` folder, and that a pull request be opened for review. *How to verify:* the merged PR contains the file and the repository shows the latest commit with the correct filename.

### Example walk‑through
Say you run **Acme Analytics**, a 30‑person SaaS that offers data‑visualization tools. Your comparison page lives at `https://acme.com/compare`. In step 1 you write a brief paragraph: “Comparison of Acme’s Standard, Pro, and Enterprise plans, targeting the URL above.” In step 2 you provide a JSON‑LD starter:

```json
{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "url": "https://acme.com/pricing/standard",
      "name": "Standard",
      "description": "Basic analytics with up to 5 dashboards."
    },
    {
      "@type": "ListItem",
      "position": 2,
      "url": "https://acme.com/pricing/pro",
      "name": "Pro",
      "description": "Advanced analytics with unlimited dashboards."
    },
    {
      "@type": "ListItem",
      "position": 3,
      "url": "https://acme.com/pricing/enterprise",
      "name": "Enterprise",
      "description": "Full suite including custom integrations."
    }
  ]
}
```

You attach the same three rows in a CSV, matching the order. The developer inserts the script into the page head, runs the Rich Results Test, sees no errors, and confirms three ListItem entries. After the pull request merges, the schema is live and indexed as AI‑ready data.

## Common pitfalls and how to spot them
- **Missing `@context`** – The Rich Results Test will flag “No @context found.” Check the first line of the JSON‑LD script.
- **Incorrect array name** – Using `items` instead of `itemListElement` prevents detection. Verify the property name matches the schema example.
- **Broken URLs** – If any `url` points to a 404 page, the validator warns “URL not reachable.” Crawl each link before finalizing.
- **Duplicate positions** – Two ListItem objects with the same `position` cause ordering warnings. Count rows to ensure each position is unique.
- **Placing the script in the body** – Some CMSes move scripts to the bottom, which can be ignored by crawlers. Open the page source and confirm the `` tag sits inside the ``.

Address each symptom before the sprint ends; otherwise the schema may be ignored by search engines and you lose the AI‑ready advantage.

[See how we do it](/services/seo-growth)

**Expanding the “What you need before the sprint”**
- **URL format rules** – Decide whether the comparison page will use a clean slug (e.g., `/compare-plans`) or include query strings for tracking (`?utm_source=seo`). If you plan to use query parameters, list every allowed parameter in the brief so the developer can whitelist them in the server config.
- **Schema version** – Schema.org updates annually, but the core `ItemList` definition has been stable for several releases. State the version you are targeting (e.g., “Schema.org 2023‑05”) so the developer knows which documentation to follow.
- **Property defaults** – Some fields, like `description`, are optional but improve AI‑readability. If you want a default fallback (e.g., “No description provided”), include that rule in the brief.
- **Access control** – If the page lives behind a login or feature flag, grant the developer a temporary token or staging environment that returns a 200 response. Without this, the Rich Results Test will see a 401/403 and mark the page as failing.
- **Version‑control location** – Specify the exact repository branch where the JSON‑LD file should be added (for example, `feature/comparison-schema`). This prevents accidental merges into the main branch before the sprint ends.

**Adding granularity to “Step‑by‑step brief”**
**Step 1 – Define the page scope (expanded)**
- Write a one‑sentence purpose that will appear as the page’s ``; this description is also used by AI‑search engines when they surface the comparison.
- Include a “fallback content” note: if the schema fails to load, the page should still render a plain HTML table of the features so users never see a blank section.

**Step 2 – Specify the JSON‑LD structure (expanded)**
- Add an explicit `@id` property that points to a permanent URL for the list (e.g., `https://acme.com/compare#features`). This makes it easier for crawlers to de‑duplicate the data across multiple pages.
- For each `ListItem`, also provide a `sku` or `productID` if the feature corresponds to a distinct SKU. The brief can include a column header named `sku` that the developer will copy into the JSON‑LD.

**Step 3 – Map the feature data (expanded)**
- Include a sanity‑check column called `isActive` that marks a feature as true/false. The developer should filter out any rows where `isActive` is false before generating the final JSON‑LD.
- Provide a small script snippet (in Python or JavaScript) that reads the CSV and outputs the JSON‑LD array. Even if the developer writes a custom parser, the script serves as a reference and reduces the chance of mis‑ordered fields.

**Step 4 – Define testing steps (expanded)**
- Run the Rich Results Test on both the staging URL (`https://staging.acme.com/compare`) **and** the production URL after deployment. Differences often appear because production servers add security headers that block schema scripts.
- Capture the raw JSON response from the Rich Results Test (using the “View JSON” button) and store it in the shared folder. Later, the QA team can diff this file against the source JSON‑LD to ensure nothing was altered by the build pipeline.

**Step 5 – Set delivery format (expanded)**
- Require the pull request description to include a checklist item: “✅ JSON‑LD validated with Rich Results Test, no errors.” This makes the acceptance criteria visible to reviewers.
- Ask the developer to add a unit test in the repository’s test suite that loads the JSON‑LD file and asserts that every required property (`@type`, `itemListElement`, `position`, `url`, `name`) exists. Continuous‑integration pipelines will then automatically catch regressions.

**Deepening the “Example walk‑through”**
Say you run **Acme Analytics**, a 30‑person SaaS that offers data‑visualization tools. The comparison page lives at `https://acme.com/compare`.

- **Data preparation** – The spreadsheet contains an extra column called `sku` with values `STD-001`, `PRO-002`, `ENT-003`. The brief tells the developer to map `sku` to a new property `productID` inside each `ListItem`.
- **Script snippet** – You provide this short Node.js helper:

```js
const fs = require('fs');
const csv = require('csv-parser');
const rows = [];

fs.createReadStream('features.csv')
  .pipe(csv())
  .on('data', (row) => rows.push(row))
  .on('end', () => {
    const jsonLD = {
      "@context": "https://schema.org",
      "@type": "ItemList",
      "itemListElement": rows.map((r, i) => ({
        "@type": "ListItem",
        "position": i + 1,
        "url": r.url,
        "name": r.name,
        "description": r.description,
        "productID": r.sku
      }))
    };
    console.log(JSON.stringify(jsonLD, null, 2));
  });
```

Running this script produces a JSON‑LD block that matches the three rows in the CSV and adds the `productID` field. The developer copies the output into `comparison-schema.json` and commits it.

- **Testing verification** – After the PR merges, you open the Rich Results Test for `https://acme.com/compare`. The tool shows the `ItemList` with three `ListItem` entries, each containing `productID`. No warnings appear, confirming that the extra property does not break validation.

- **CI check** – The repository’s `npm test` script includes a test that loads `comparison-schema.json` and asserts that the length of `itemListElement` equals three. The build passes, guaranteeing that future changes to the CSV will automatically be reflected in the schema without manual re‑validation.

**Extending “Common pitfalls and how to spot them”**
- **Schema drift due to minification** – Some build tools compress JavaScript files and inadvertently remove line breaks inside the JSON‑LD script, turning it into a single line that exceeds the parser’s size limit. Verify the rendered page source; the script should remain readable JSON (no escaped newlines).
- **Incorrect MIME type** – If the server serves the page with `Content-Type: text/html` but the JSON‑LD is embedded inside a `` tag, crawlers will still read it, but some validators expect the correct MIME type. Ensure the `` tag includes the `type` attribute exactly as shown.
- **Dynamic URL generation** – When feature URLs are built client‑side with JavaScript, the schema may render before the final URL is known, producing placeholder strings like `#`. In that case, generate the JSON‑LD server‑side or use a build‑time script that inserts the final URLs.
- **Missing `@id` causing duplicate entities** – Without a stable `@id`, crawlers may treat each `ListItem` as a separate unnamed entity, leading to fragmented knowledge graphs. Add a deterministic identifier (for example, the page URL plus `#item-` plus the position) to each `ListItem`.
- **Over‑escaping characters** – JSON‑LD must use standard JSON escaping. If a description contains a double quote, it should be escaped as `\"`. A common failure is to output raw HTML quotes, which the Rich Results Test flags as “Invalid JSON”. Double‑check that any generated JSON‑LD runs through a JSON serializer rather than string concatenation.

By anticipating these issues early in the brief and adding explicit verification steps, the sprint stays on schedule and the comparison page becomes an AI‑ready asset that search engines can surface reliably.

Comppound’s system includes a template for this brief, ensuring nothing is missed. [See how we do it](/services/seo-growth).

## Keep reading

- [Brief a Feature Comparison Page for Dev Sprint Delivery](/blog/brief-a-feature-comparison-page-for-dev-sprint-delivery)
- [How to Brief Developer for Feature Toggle Page in One Day](/blog/how-to-brief-developer-for-feature-toggle-page-in-one-day)
- [Brief a Developer for AI-Ready Release Notes in One Sprint](/blog/brief-a-developer-for-ai-ready-release-notes-in-one-sprint)

## Frequently asked questions

### Do I need to update the schema every time I add a new feature?

Yes. The schema should reflect the current state of the comparison page. Add a new ListItem entry and increment the position numbers as needed, then re‑run the Rich Results Test before pushing changes.

### Can I use Microdata instead of JSON‑LD for this page?

Microdata works, but JSON‑LD is easier to maintain and is the preferred format for AI‑ready markup because it keeps the data separate from the HTML layout.

### What if my CMS doesn’t let me edit the  section?

Inject the JSON‑LD via a server‑side include or a tag manager that supports script injection. The key is that the script ends up inside the `` when the page renders.

## About Comppound

Comppound runs SEO and AI search for B2B SaaS companies: a person sets the plan and reviews samples and every high-risk page, and AI speeds up production.

- [Check a page free](https://comppound.com/tools/seo-checker): Check one of your pages before you change anything else
- [See pricing](https://comppound.com/pricing): Want the content written, reviewed and published for you?
