Recovery Playbooks
Search Console Sitemap Shows Fewer Pages Than WordPress: What to Check
A practical checklist for fixing Search Console sitemap counts when WordPress has more published posts than Google sees in the submitted sitemap.
Last reviewed: June 8, 2026
Search Console can show a successful sitemap while still reporting fewer discovered pages than your CMS actually has. That gap is easy to miss because the status looks healthy: the sitemap is readable, there are no parse errors, and the submitted URL is correct. The problem is usually not Search Console. It is the sitemap generator, cache layer, canonical logic, or publish workflow.
This guide is for WordPress operators, headless frontend teams, and technical SEOs who see a mismatch such as 148 published posts in WordPress but only 102 URLs discovered in Search Console. The goal is to separate reporting delay from a real discovery bug and fix the path that tells Google which URLs should exist.
Key takeaways
- A successful sitemap only proves that Google could fetch and parse the sitemap file. It does not prove every published post is listed.
- Headless frontends often cap sitemap queries accidentally, especially when the WordPress REST API defaults or frontend helpers limit results to 100 posts.
- The sitemap should list canonical public URLs only, not backend URLs, pagination experiments, search results, draft routes, or example URLs copied from code blocks.
First confirm the real mismatch
Start with the source of truth. In WordPress, count published posts. On a WP-CLI enabled server, use:
wp post list --post_type=post --post_status=publish --format=count
curl -sI 'https://api.example.com/wp-json/wp/v2/posts?status=publish&per_page=1&page=1' | grep -i 'x-wp-total'
curl -s https://example.com/sitemap.xml | grep -c '<url>'
The first command checks WordPress directly. The REST response header should show the same broad total. The sitemap count should then equal the pages you intentionally expose, plus any index pages such as the home page or archive page.
If WordPress says 148 posts and the sitemap has 102 URLs, the crawler is not seeing the full inventory. Waiting will not fix a hard cap in the sitemap generator.
Common causes of a short sitemap
- The frontend asks WordPress for only one page of posts. WordPress REST API responses are paginated. If the frontend requests
per_page=100and never fetches page 2, every post after the first 100 is absent from the sitemap. - The sitemap route uses a homepage helper instead of an all-posts helper. A function named
getPosts(100)is useful for cards and feeds, but it is often wrong for sitemap generation. Sitemaps need a complete canonical URL list. - The sitemap is cached longer than the publish workflow assumes. A Next.js, Cloudflare, or plugin cache can keep an old sitemap visible after content was published. Check the live XML, not only local build output.
- Canonical URLs and listed URLs disagree. If the sitemap lists backend URLs, www URLs, HTTP URLs, or parameter URLs while article pages canonicalize to a different host, Google receives weaker signals.
- Unwanted URLs are discoverable through internal links. Examples inside code blocks can become crawlable if they are rendered as links. Keep sample paths as code unless they are real pages.
Fix pattern for headless WordPress
The sitemap should fetch every REST page and flatten the results before mapping posts to public URLs. The exact code depends on the frontend, but the logic should look like this:
async function getAllPublishedPosts() {
const firstPage = await fetchPosts({ page: 1, perPage: 100 });
const remainingPages = Array.from(
{ length: Math.max(0, firstPage.totalPages - 1) },
(_, index) => index + 2
);
const remaining = await Promise.all(
remainingPages.map((page) => fetchPosts({ page, perPage: 100 }))
);
return [firstPage.posts, ...remaining.map((result) => result.posts)].flat();
}
Then the sitemap should map those posts to the canonical frontend domain:
return [
{ url: siteUrl },
{ url: `${siteUrl}/blog` },
...posts.map((post) => ({
url: `${siteUrl}/blog/${post.slug}`,
lastModified: post.modifiedIso,
})),
];
Do not use the WordPress backend permalink if the public site is a separate frontend. The sitemap is a promise about what users and Google should reach publicly.
Validation checklist after the fix
- The live sitemap count matches the intended URL inventory.
- The newest and oldest published posts both appear in the XML.
- Each sitemap URL returns
200on the public frontend. - Each article source has a canonical tag matching the sitemap URL.
robots.txtpoints to the canonical sitemap location.- Search Console Sitemaps report shows the sitemap as successful after resubmission.
What not to fix
Do not add every URL that Google has ever crawled. A sitemap is not a cleanup bucket for 404s, redirects, search URLs, backend admin paths, or old sample routes. If Google found bad URLs, fix the internal link source or let real 404s age out. Keep the sitemap limited to stable canonical pages that deserve discovery.
Related reading
If Search Console already shows non-indexed examples after the sitemap is fixed, continue with the Crawled – currently not indexed WordPress checklist. If the issue is redirect cleanup rather than discovery, use the Page with redirect guide.
