plugins/aem/edge-delivery-services-content-ops/skills/sitemap-audit/SKILL.md
Validate an AEM Edge Delivery Services sitemap.xml against actual site content. Cross-references the sitemap with the query index, checks URL reachability, validates lastmod dates, and identifies missing or orphaned pages. Use when auditing SEO health, preparing for launch, or investigating indexing issues.
npx skillsauth add adobe/skills sitemap-auditInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Validate an EDS sitemap.xml against published content, cross-reference with the query index, check URL health, and produce a report with specific additions, removals, and fixes.
This skill fetches external web pages and XML/JSON endpoints for analysis. When fetching:
For EDS sitemap configuration details (helix-sitemap.yaml, glob rules, multilingual setup, robots.txt behavior, query index usage), see references/eds-sitemap-reference.md.
Not suited for non-EDS sites, generating sitemaps from scratch, or sites with 10,000+ URLs (spot-check a sample instead).
const robotsResp = await fetch('https://{domain}/robots.txt');
Check for:
Sitemap: directive -- must point to the production URL, not .aem.live or .aem.page.Disallow rules -- verify nothing blocks /sitemap.xml. Disallow: / on production is a blocker.// Primary location
const sitemapResp = await fetch('https://{domain}/sitemap.xml');
// Fallback: try the .aem.live origin
const fallbackResp = await fetch('https://main--{repo}--{owner}.aem.live/sitemap.xml');
Parse the XML and extract each <loc>, <lastmod>, total URL count, and whether a sitemap index is used. If 404 on all locations, inform the user no sitemap is configured and stop the audit.
For each URL, strip the domain to get the path, remove trailing slashes, and flag:
www.example.com vs example.com)..html extensions (EDS uses extensionless URLs).#section).The query index is the canonical source of truth for published EDS content.
// Fetch all pages (paginate until data is empty)
let offset = 0;
const limit = 256;
let allEntries = [];
let page;
do {
const resp = await fetch(`https://{domain}/query-index.json?offset=${offset}&limit=${limit}`);
page = await resp.json();
allEntries = allEntries.concat(page.data);
offset += limit;
} while (page.data.length === limit);
Scan the sitemap for URLs containing /fragments/ or /drafts/ -- these are blockers. Also flag utility paths (/nav, /footer, /search, /404) as warnings.
/drafts/, /fragments/, /nav, /footer, pages with robots: noindex). Everything else is a gap.<lastmod> differs from query index lastModified. Indicates a properties.lastmod mapping issue.// Check each sitemap URL
const resp = await fetch(url, { method: 'HEAD', redirect: 'manual' });
Flag: 404 = blocker (remove from sitemap), 301/302 = warning (update URL), 5xx = warning (re-check later).
lastmod to prioritize crawling.lastmod; suggests dates are set to build/deploy time, not actual content modification.YYYY-MM-DD or YYYY-MM-DDThh:mm:ssTZD.<link rel="canonical"> on 5-10 pages..html extensions -- warning; EDS uses extensionless URLs.http:// protocol -- warning; all URLs should use https://.| Metric | Count | |--------|-------| | Total URLs in sitemap | X | | Valid (200 OK) | X | | Broken (404) | X | | Redirected (301/302) | X | | Missing from sitemap (in query index only) | X | | Stale entries (in sitemap only) | X | | Fragment/draft leaks | X | | Lastmod mismatches | X |
Pages in the query index but missing from the sitemap (excluding intentional exclusions). List path, title, and reason.
Sitemap URLs that return 404 or redirect. List URL and reason.
Other issues: fragment/draft leaks, missing lastmod, robots.txt problems, .html extensions, domain mismatches. For each, list the affected URLs and the specific helix-sitemap.yaml change to make.
/drafts/** and /fragments/** to exclude in helix-sitemap.yaml).lastmod mapping (properties.lastmod: lastModified).Sitemap: directive uses the production domain.helix-sitemap.yaml via Sidekick and verify at /sitemap.xml.For troubleshooting common issues, see references/eds-sitemap-reference.md.
helix-sitemap.yaml. Most EDS sitemap problems are configuration problems.tools
Use the run-workflow MCP to discover, compose, execute, publish, and save Adobe Firefly workflows. TRIGGER when: user asks what actions are available, what the MCP can do, how to process images/video/3D via workflow, wants to build/run/save/publish a workflow, OR pastes any workflow/batch/execution ID. BARE ID (UUID/workflowId/batchId) = INSPECT ONLY — call inspect_run, NEVER run_workflow_submit. ALWAYS call list_actions first for capability/discovery questions. DO NOT TRIGGER for direct Firefly API calls without MCP (use firefly-api-specs).
tools
Run predefined featured workflows via run-workflow MCP. TRIGGER when user names a featured workflow (retargeting, banners at scale, localization, packaging, banner advertising, etc.) or asks to run a known marketing/production workflow. Requires run-workflow MCP. ALWAYS call get_featured_workflow before compose_workflow. DO NOT TRIGGER for custom one-off workflows with no named template — use run-workflow skill.
tools
Migrate an Adobe Commerce App Builder project from the Integration Starter Kit or Checkout Starter Kit to the new App Management approach. Run from the root of the App Builder project to be migrated. Pass --auto to skip confirmation prompts (suitable for CI or batch use) — auto mode prints a summary of all Q&A questions answered with their defaults. Pass --doc-scan-only to scan README.md and env.dist for outdated content without modifying any files. Use when the user wants to migrate an App Builder project from the Integration Starter Kit or Checkout Starter Kit to the App Management approach, or mentions upgrading their Adobe Commerce extension architecture.
development
Add or modify webhook interceptors in an Adobe Commerce app. Use when the user wants to intercept Commerce operations to validate input, append data, or modify behavior — before or after execution. Requires a base app initialized with commerce-app-init.