Content operations skills for AEM Edge Delivery Services: page auditing, SEO optimization, AI search (GEO), WCAG accessibility, bulk metadata, structured data, sitemap validation, and content diffing. Complements the EDS development skills with operational tooling for content teams.
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Audit a query index: what is in it, who reads it, what is missing, and what to change in its definition. Background, the definition syntax and a troubleshooting table are in references/query-index-context.md.
.aem.live or .aem.page host, and admin.hlx.page for that site.AEM_ADMIN_TOKEN environment variable and never print it.scripts/index-report.mjs is in this skill's directory. It needs Node.js and nothing else.
node scripts/index-report.mjs "https://<branch>--<repo>--<owner>.aem.live/query-index.json" \
--sitemap="https://<branch>--<repo>--<owner>.aem.live/sitemap.xml" > index-report.json/query-index.json is only the default. A site can have several indexes, each at the target of its definition, for example /blog/query-index.json. Run the script once per index..aem.live host: a production CDN can return the whole index where .aem.live returns 1000 entries..aem.page and .aem.live: it holds published pages only.--check=25 is the default: the script requests the 25 oldest indexed paths. Raise it for a full check, or pass --check=0.The report holds total, requests (more than 1 means the index has more than 1000 entries), uncompressedBytes, for each property its fillRate and number of distinct values, and the sitemap and status results.
The definition is part of the site configuration. It is not a file in the repository.
Ask the user for it from the Index Admin tool, or
read it from the Admin API, if the user has a token:
curl -s -H "x-auth-token: $AEM_ADMIN_TOKEN" \
"https://admin.hlx.page/config/<org>/sites/<site>/content/query.yaml"If neither is possible, work from the properties in the report and say that the definition was not seen.
Reconcile the definition with the report before you go on:
path is the exception: it is always there.GET https://admin.hlx.page/index/<org>/<site>/<branch>/<path> with the same token.For each place in the project's code that fetches the index, note the properties it reads and whether it passes limit or pages with offset. A fetch without limit gets the first 1000 entries: on an index with more, that is a list or a search that silently misses pages.
The sitemap reads the index too, when the sitemap configuration names it as its source:
robots: pages with noindex are left out of the sitemap only when the index has this column.lastModified: the <lastmod> dates of the sitemap.Never propose to remove path, robots or lastModified because no block reads them.
| In the report | What it means | Propose |
|---|---|---|
requests is more than 1 | More than 1000 entries. | For each consumer from Step 3 that doesn't page: page with offset and limit, or read a smaller index. |
total is close to 50,000 | An index can't hold more than 50,000 pages. | Split it into several indexes with include paths. |
uncompressedBytes is several MB | A consumer that reads the whole index makes every visitor download it. A response may not exceed 6 MB compressed. | Remove properties nobody reads, or split the index. |
A property with fillRate 0 | The selector matches nothing, or no page has the metadata. | Fix the selector or remove the property. |
A low fillRate | Not a defect by itself: robots is only filled on noindex pages. | Remove it only when no consumer reads it. |
sitemap.notInIndex | Published pages that the index lacks. They are outside the include paths, inside an exclude, part of another index, or were published before the definition existed. | Change the paths, or publish the pages again. |
sitemap.notInIndexCount is 0 | Nothing is missing, or the sitemap is built from this index. | Ask the user which pages they miss, and check each with the Admin API call from Step 2. |
sitemap.notInSitemapWithNoindex | Expected. | Nothing. |
status.notOk with 301 or 302 | A redirect was added for a path that is still published. The index keeps the entry. | Unpublish the page. |
status.notOk with 404 | Unexpected: the index holds published pages only. | List the paths and ask the user to reindex. |
Write the report for the user:
references/query-index-context.md, with a target for every index..tessl-plugin
skills
accessibility-fix
bulk-metadata
content-audit
content-diff
cwv-optimizer
geo-rewrite
heading-optimizer
image-seo
internal-linking
link-rot-scanner
optel-interpreter
performance-budget
product-page-seo
query-index-optimizer
sitemap-audit
structured-data