SEO & Digital Marketing Consultant » Technical » How to Build a Custom XML Sitemap in WordPress

How to Build a Custom XML Sitemap in WordPress

/

WordPress Custom Sitemap

XML sitemaps are important for SEO, it provides a list of pages for search engines to crawl from your website. They can also be used to help inform about the structure of your content.

There are plugins out there such as Yoast SEO that can generate them automatically in WordPress but there might be certain cases where you need to build a custom sitemap. For example, you might have hosting restrictions, specific URL requirements, or using a reverse proxy.

This guide explains how to create a custom XML sitemap in WordPress for a reverse proxy use case but can be adapted for other cases too…


Step 1: Intercept Sitemap Requests

Intercept requests for custom sitemap URLs (e.g., /custom-sitemap_index.xml) and generate the required XML directly. Use the init hook to catch the requests early.

add_action('init', function () {
    if (isset($_SERVER['REQUEST_URI'])) {
        $custom_sitemaps = [
            '/custom-sitemap_index.xml' => 'index',
            '/custom-post-sitemap.xml' => 'post',
            '/custom-page-sitemap.xml' => 'page',
            // Additional cases for categories and authors...
        ];

        foreach ($custom_sitemaps as $path => $type) {
            if (strpos($_SERVER['REQUEST_URI'], $path) === 0) {
                if ($type === 'index') {
                    generate_custom_sitemap_index();
                } else {
                    generate_custom_sitemap($type);
                }
                exit;
            }
        }
    }
});

This ensures WordPress processes the correct XML before default templates or redirects interfere.


Step 2: Generate the Sitemap Index

The sitemap index acts as a directory for individual content sitemaps (e.g., posts, pages, categories).

function generate_custom_sitemap_index() {
    $sitemaps = [
        'custom-post-sitemap.xml'     => $wpdb->get_var("SELECT MAX(post_modified_gmt) FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'post'"),
        'custom-page-sitemap.xml'     => $wpdb->get_var("SELECT MAX(post_modified_gmt) FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'page'"),
'custom-post-sitemap.xml' => '2025-01-31T15:44:00+00:00',
        // Additional cases for categories and authors...
    ];

    header('Content-Type: application/xml; charset=utf-8');
    echo '<?xml version="1.0" encoding="UTF-8"?>';
    echo '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';

    foreach ($sitemaps as $slug => $lastmod) {
        $url = site_url($slug);  
        echo "<sitemap>";
        echo "<loc>$url</loc>";
        echo "<lastmod>$lastmod</lastmod>";
        echo "</sitemap>";
    }

    echo '</sitemapindex>';
    exit;
}

Step 3: Create Content-Specific Sitemaps

For each content type (e.g., posts, pages), generate a corresponding XML file. Replace the domain in URLs when needed, such as for reverse proxies.

function generate_custom_sitemap($type) {
    global $wpdb;

    header('Content-Type: application/xml; charset=utf-8');
    echo '<?xml version="1.0" encoding="UTF-8"?>';
    echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';

    $site_url = get_site_url();  

    switch ($type) {
        case 'post':
            $posts = $wpdb->get_results("SELECT ID, post_modified_gmt FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'post'");
            foreach ($posts as $post) {
                $url = str_replace($site_url, 'https://proxy-domain.com', get_permalink($post->ID));
                $lastmod = gmdate('Y-m-d\TH:i:s+00:00', strtotime($post->post_modified_gmt));
                echo "<url><loc>$url</loc><lastmod>$lastmod</lastmod></url>";
            }
            break;

        case 'page':
            $pages = $wpdb->get_results("SELECT ID, post_modified_gmt FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'page'");
            foreach ($pages as $page) {
                $url = str_replace($site_url, 'https://proxy-domain.com', get_permalink($page->ID));
                $lastmod = gmdate('Y-m-d\TH:i:s+00:00', strtotime($page->post_modified_gmt));
                echo "<url><loc>$url</loc><lastmod>$lastmod</lastmod></url>";
            }
            break;

        // Additional cases for categories and authors...
    }

    echo '</urlset>';
    exit;
}

Step 4: Prevent Trailing Slash Issues

To avoid WordPress redirecting sitemap URLs to versions with trailing slashes, disable canonical redirects for sitemap paths.

add_filter('redirect_canonical', function ($redirect_url, $requested_url) {
    $sitemap_paths = [
        'custom-sitemap_index.xml',
        'custom-post-sitemap.xml',
        'custom-page-sitemap.xml',
        // Additional cases for categories and authors...
    ];

    foreach ($sitemap_paths as $path) {
        if (strpos($requested_url, $path) !== false) {
            return false; // Disable redirect
        }
    }

    return $redirect_url;
}, 10, 2);

Step 5: Add Rewrite Rules

Register custom rewrite rules to make WordPress recognise sitemap URLs.

function add_custom_sitemap_rewrite_rules() {
    add_rewrite_rule('^custom-sitemap_index\.xml$', 'index.php', 'top');
    add_rewrite_rule('^custom-post-sitemap\.xml$', 'index.php', 'top');
    add_rewrite_rule('^custom-page-sitemap\.xml$', 'index.php', 'top');
    // Additional cases for categories and authors...
}
add_action('init', 'add_custom_sitemap_rewrite_rules');

Flush the rewrite rules after activation by visiting Settings > Permalinks and clicking Save Changes.


Testing

Once the plugin is activated, verify the following URLs:

  • /custom-sitemap_index.xml
  • /custom-post-sitemap.xml
  • /custom-page-sitemap.xml

Check the <loc> tags in the XML files to ensure the URLs are correct, especially if a reverse proxy is in use.

contact.

From bespoke SEO strategies, content services, to a modern high-performance website-it’s all based on your requirement.

helpful SEO & digital marketing tips.

recent articles.

Read articles and guides to help you learn about SEO, how it works, and other useful tips to help generate organic traffic.