WordPress 5.5 Built-in XML Sitemaps: Disable Providers, Filter Entries, and Extend

WordPress 5.5 shipped a built-in XML sitemap system, removing one of the most common reasons to install an SEO plugin just for sitemaps. The sitemap index is available at /wp-sitemap.xml and links to sub-sitemaps for posts, pages, custom post types (public, with a front-end URL), taxonomies, and users — all automatically generated from the existing WordPress data model. Each sub-sitemap contains up to 2 000 URLs by default, and the system creates additional paginated sub-sitemaps when a provider exceeds that limit. For most sites this is sufficient without any configuration. The API is extensible: you can disable individual providers, change the URL limit per sitemap page, modify the URLs included in any provider’s output, and register completely custom sitemap providers for non-standard content (such as product feeds or PDFs). You can also disable the built-in sitemaps entirely and serve your own.

Problem: WordPress 5.5's built-in sitemap includes a /wp-sitemap-users-1.xml entry that exposes all author username slugs. You also want to exclude a private CPT from the sitemap and add your own event CPT which the default system doesn't include.

Solution: Use the wp_sitemaps_add_provider filter to remove the users provider. Register a custom WP_Sitemaps_Provider for the event CPT, and filter wp_sitemaps_posts_query_args to exclude the private CPT.

<?php
// ── Remove the Users sitemap provider ────────────────────────────────
add_filter( 'wp_sitemaps_add_provider', function ( $provider, $name ) {
    if ( 'users' === $name ) {
        return false; // returning false removes the provider
    }
    return $provider;
}, 10, 2 );

// ── Exclude a specific post type from sitemaps ────────────────────────
add_filter( 'wp_sitemaps_post_types', function ( $post_types ) {
    unset( $post_types['private_doc'] ); // remove 'private_doc' CPT
    return $post_types;
} );

// ── Limit URLs per sub-sitemap page (default is 2000) ─────────────────
add_filter( 'wp_sitemaps_max_urls', function ( $max ) {
    return 1000;
} );

// ── Disable the built-in sitemaps entirely ────────────────────────────
add_filter( 'wp_sitemaps_enabled', '__return_false' );

// ── Modify entries in a specific sitemap ──────────────────────────────
// Filter the URLs included in the posts sitemap
add_filter( 'wp_sitemaps_posts_query_args', function ( $args, $post_type ) {
    if ( 'post' === $post_type ) {
        // Only include posts from specific categories
        $args['tax_query'] = [ [
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => [ 'news', 'tutorials' ],
        ] ];
    }
    return $args;
}, 10, 2 );

NOTE: The built-in WordPress sitemaps do not include <lastmod>, <changefreq>, or <priority> tags — Google's John Mueller has confirmed these are ignored by Google's crawler anyway, so their absence is intentional. If your SEO requirements include those tags (e.g. for Bing), you will need a full-featured sitemap plugin like Yoast SEO or Rank Math, or a custom WP_Sitemaps_Provider implementation that overrides the URL list with those fields.