Extend the WordPress Built-In Sitemap to Include Custom Post Types and Taxonomies

A WordPress XML sitemap lists all indexable URLs on the site and signals their relative priority and change frequency to search crawlers, helping Googlebot discover new and updated content faster than relying on link discovery alone. WordPress 5.5 introduced a built-in sitemaps module that generates sitemaps automatically for posts, pages, and built-in post types, but it excludes custom post types, custom taxonomies, and author archives unless explicitly extended. The built-in sitemap is available at /wp-sitemap.xml and provides a sitemap index linking to individual sub-sitemaps for each object type — this multi-file structure prevents any single file from exceeding the 50,000 URL limit that search engines impose. The wp_sitemaps_post_types and wp_sitemaps_taxonomies filters control which post types and taxonomies appear in the sitemap without disabling the built-in module. Adding a custom URL provider extends the sitemap with URLs that are not standard WordPress object types — for example, date-based archive URLs or paginated author archives. Custom providers extend WP_Sitemaps_Provider and implement get_url_list() and get_max_num_pages() to paginate large URL sets correctly. Setting lastmod from the most recently updated post in a given section helps crawlers prioritise re-crawling recently changed areas over static pages. The wp_sitemaps_index_entry filter modifies each sitemap index entry to add or change metadata before it is output. The canonical URL post ensures the URLs in the sitemap match the canonical link tags on each page — discrepancies between sitemap URLs and canonical tags confuse crawlers. The Open Graph post covers complementary metadata that affects how search and social referrals present the pages listed in the sitemap. After extending the sitemap, submit the /wp-sitemap.xml index URL in Google Search Console under Sitemaps to trigger immediate crawl prioritisation of the new entries.

Problem: WordPress's built-in sitemap excludes custom post types, custom taxonomies, and author archives, leaving those URLs undiscovered by search crawlers unless a third-party SEO plugin is installed or the sitemap is extended in code.

Solution: Use the wp_sitemaps_post_types and wp_sitemaps_taxonomies filters to include registered custom types, and add a custom WP_Sitemaps_Provider subclass for URL sets that fall outside the standard object model.

// Add custom post types and taxonomies to the built-in sitemap
add_filter('wp_sitemaps_post_types', function(array $post_types): array {
    $post_types['portfolio'] = get_post_type_object('portfolio');
    return $post_types;
});

add_filter('wp_sitemaps_taxonomies', function(array $taxonomies): array {
    $taxonomies['project_type'] = get_taxonomy('project_type');
    return $taxonomies;
});

// Exclude private or utility post types from the sitemap
add_filter('wp_sitemaps_post_types', function(array $post_types): array {
    unset($post_types['attachment']);
    return $post_types;
});

// Custom URL provider: date-based yearly archives
class My_Year_Archive_Sitemap extends WP_Sitemaps_Provider {
    public function __construct() {
        $this->name        = 'date-archives';
        $this->object_type = 'date';
    }

    public function get_url_list(int $page_num, string $object_subtype = ''): array {
        $years   = get_transient('sitemap_years');
        if (!$years) {
            global $wpdb;
            $years = $wpdb->get_col(
                "SELECT DISTINCT YEAR(post_date) FROM {$wpdb->posts}
                 WHERE post_status='publish' AND post_type='post'"
            );
            set_transient('sitemap_years', $years, DAY_IN_SECONDS);
        }
        return array_map(function($year) {
            return ['loc' => get_year_link($year)];
        }, $years);
    }

    public function get_max_num_pages(string $object_subtype = ''): int { return 1; }
}

add_action('init', function() {
    wp_register_sitemap_provider('date-archives', new My_Year_Archive_Sitemap());
});

NOTE: Submit the sitemap index URL /wp-sitemap.xml in Google Search Console and Bing Webmaster Tools after extending it — both tools display per-sub-sitemap crawl statistics that help confirm the new custom post type and taxonomy URLs are being discovered and indexed.